{-# LANGUAGE NoImplicitPrelude #-} module Data.Aviation.Casa.AbbreviationsAndAcronyms.Search( all_Acronym_name_index , all_Acronym_meaning_index , all_Acronym_source_index , searchIndexName , searchIndexMeaning , searchIndexSource , searchIndexNameSource , searchIndexNameMeaning , searchIndexMeaningSource , searchIndexNameMeaningSource , searchFuzzyName , searchFuzzyMeaning , searchFuzzySource , searchFuzzyNameMeaning , searchFuzzyNameSource , searchFuzzyMeaningSource , searchFuzzyNameMeaningSource ) where import Control.Applicative((<|>)) import Control.Category((.)) import Control.Lens((^.)) import Data.Aviation.Casa.AbbreviationsAndAcronyms.Acronym(Acronym(Acronym), allAcronyms, name, meaning, source) import Data.Bool(Bool) import Data.Char(isAlpha, toUpper) import Data.Foldable(foldl') import Data.Function(($)) import Data.Functor((<$>), fmap) import Data.List(sortBy, filter) import Data.Map(Map) import qualified Data.Map as Map(fromList, lookup, insertWith, toList) import Data.Maybe(Maybe) import Data.Ord(Ord((>)), compare) import Data.String(String) import Data.Monoid.Textual(TextualMonoid) import qualified Text.Fuzzy as Fuzzy(filter, score) import Text.Fuzzy(Fuzzy(Fuzzy)) all_Acronym_name_index :: Map String (String, String) all_Acronym_name_index = Map.fromList ((\(Acronym _name _meaning _src) -> (_name, (_meaning, _src))) <$> allAcronyms) all_Acronym_meaning_index :: Map String (String, String) all_Acronym_meaning_index = Map.fromList ((\(Acronym _name _meaning _src) -> (_meaning, (_name, _src))) <$> allAcronyms) all_Acronym_source_index :: Map String (String, String) all_Acronym_source_index = Map.fromList ((\(Acronym _name _meaning _src) -> (_src, (_name, _meaning))) <$> allAcronyms) searchIndexName :: String -> Maybe Acronym searchIndexName s = let s' = filter isAlpha . fmap toUpper $ s in (\(_meaning, _src) -> Acronym s _meaning _src) <$> Map.lookup s' all_Acronym_name_index searchIndexMeaning :: String -> Maybe Acronym searchIndexMeaning s = let s' = filter isAlpha . fmap toUpper $ s in (\(_name, _src) -> Acronym _name s _src) <$> Map.lookup s' all_Acronym_meaning_index searchIndexSource :: String -> Maybe Acronym searchIndexSource s = let s' = filter isAlpha . fmap toUpper $ s in (\(_name, _meaning) -> Acronym s _name _meaning) <$> Map.lookup s' all_Acronym_source_index searchIndexNameMeaning :: String -> Maybe Acronym searchIndexNameMeaning s = searchIndexName s <|> searchIndexMeaning s searchIndexNameSource :: String -> Maybe Acronym searchIndexNameSource s = searchIndexName s <|> searchIndexSource s searchIndexMeaningSource :: String -> Maybe Acronym searchIndexMeaningSource s = searchIndexMeaning s <|> searchIndexSource s searchIndexNameMeaningSource :: String -> Maybe Acronym searchIndexNameMeaningSource s = searchIndexName s <|> searchIndexMeaning s <|> searchIndexSource s searchFuzzyName :: String -> String -> String -> Bool -> [Fuzzy Acronym String] searchFuzzyName s before after cas = Fuzzy.filter s allAcronyms before after (^. name) cas searchFuzzyMeaning :: String -> String -> String -> Bool -> [Fuzzy Acronym String] searchFuzzyMeaning s before after cas = Fuzzy.filter s allAcronyms before after (^. meaning) cas searchFuzzySource :: String -> String -> String -> Bool -> [Fuzzy Acronym String] searchFuzzySource s before after cas = Fuzzy.filter s allAcronyms before after (^. source) cas searchFuzzyNameMeaning :: String -> String -> String -> Bool -> [Fuzzy Acronym String] searchFuzzyNameMeaning s before after cas = filterN s allAcronyms before after [(^. name), (^. meaning)] cas searchFuzzyNameSource :: String -> String -> String -> Bool -> [Fuzzy Acronym String] searchFuzzyNameSource s before after cas = filterN s allAcronyms before after [(^. name), (^. source)] cas searchFuzzyMeaningSource :: String -> String -> String -> Bool -> [Fuzzy Acronym String] searchFuzzyMeaningSource s before after cas = filterN s allAcronyms before after [(^. meaning), (^. source)] cas searchFuzzyNameMeaningSource :: String -> String -> String -> Bool -> [Fuzzy Acronym String] searchFuzzyNameMeaningSource s before after cas = filterN s allAcronyms before after [(^. name), (^. meaning), (^. source)] cas -- https://hackage.haskell.org/package/fuzzy-0.1.0.0/docs/Text-Fuzzy.html#v:filter filterN :: (Ord t, TextualMonoid s) => s -> [t] -> s -> s -> [t -> s] -> Bool -> [Fuzzy t s] filterN _ _ _ _ [] _ = [] filterN pattern values before after (e:es) cas = let x1 = Fuzzy.filter pattern values before after e cas x1' = Map.fromList ((\(Fuzzy o r s) -> (o, (r, s))) <$> x1) x2' = foldl' (\m e' -> let x2 = Fuzzy.filter pattern values before after e' cas in foldl' (\m' (Fuzzy o r s) -> Map.insertWith (\(s1, i1) (s2, i2) -> if i2 > i1 then (s2, i2) else (s1, i1)) o (r, s) m') m x2) x1' es in sortBy (\f1 f2 -> Fuzzy.score f2 `compare` Fuzzy.score f1) ((\(o, (r, s)) -> Fuzzy o r s) <$> Map.toList x2')