module QuickSearch.OneShot
    ( oneShot
    , oneShotTopNMatches
    , oneShotMatchesWithThreshold
    , jaro
    , jaroWinkler
    , damerauLevenshteinNorm
    ) where
import           Data.Hashable                  ( Hashable )
import qualified Data.Text                     as T
import           Data.Text.Metrics              ( damerauLevenshteinNorm
                                                , jaro
                                                , jaroWinkler
                                                )
import           QuickSearch                    ( Entry(..)
                                                , Match
                                                , QuickSearch
                                                , Score
                                                , Scorer
                                                , buildQuickSearch
                                                , matchesWithThreshold
                                                , topNMatches
                                                )
oneShot
    :: (Hashable uid1, Eq uid1, Hashable uid2, Eq uid2)
    => (  QuickSearch uid2
       -> Int
       -> Scorer
       -> T.Text
       -> [Match Score (Entry T.Text uid2)]
       )
  
    -> Int  
    -> [(T.Text, uid1)]  
    -> [(T.Text, uid2)]  
    -> Scorer  
    -> [(Entry T.Text uid1, [Match Score (Entry T.Text uid2)])]
    
oneShot :: (QuickSearch uid2
 -> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)])
-> Int
-> [(Text, uid1)]
-> [(Text, uid2)]
-> Scorer
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
oneShot QuickSearch uid2
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)]
f Int
n [(Text, uid1)]
entries [(Text, uid2)]
targets Scorer
scorer =
    let qs :: QuickSearch uid2
qs      = [(Text, uid2)] -> QuickSearch uid2
forall uid.
(Hashable uid, Eq uid) =>
[(Text, uid)] -> QuickSearch uid
buildQuickSearch [(Text, uid2)]
targets
        results :: [[Match Int (Entry Text uid2)]]
results = ((Text, uid1) -> [Match Int (Entry Text uid2)])
-> [(Text, uid1)] -> [[Match Int (Entry Text uid2)]]
forall a b. (a -> b) -> [a] -> [b]
map (QuickSearch uid2
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)]
f QuickSearch uid2
qs Int
n Scorer
scorer (Text -> [Match Int (Entry Text uid2)])
-> ((Text, uid1) -> Text)
-> (Text, uid1)
-> [Match Int (Entry Text uid2)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text, uid1) -> Text
forall a b. (a, b) -> a
fst) [(Text, uid1)]
entries
    in  [Entry Text uid1]
-> [[Match Int (Entry Text uid2)]]
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
forall a b. [a] -> [b] -> [(a, b)]
zip (((Text, uid1) -> Entry Text uid1)
-> [(Text, uid1)] -> [Entry Text uid1]
forall a b. (a -> b) -> [a] -> [b]
map (Text, uid1) -> Entry Text uid1
forall name uid. (name, uid) -> Entry name uid
Entry [(Text, uid1)]
entries) [[Match Int (Entry Text uid2)]]
results
oneShotTopNMatches
    :: (Hashable uid1, Eq uid1, Hashable uid2, Eq uid2)
    => Int  
    -> [(T.Text, uid1)]  
    -> [(T.Text, uid2)]  
    -> Scorer  
    -> [(Entry T.Text uid1, [Match Score (Entry T.Text uid2)])]
  
oneShotTopNMatches :: Int
-> [(Text, uid1)]
-> [(Text, uid2)]
-> Scorer
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
oneShotTopNMatches = (QuickSearch uid2
 -> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)])
-> Int
-> [(Text, uid1)]
-> [(Text, uid2)]
-> Scorer
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
forall uid1 uid2.
(Hashable uid1, Eq uid1, Hashable uid2, Eq uid2) =>
(QuickSearch uid2
 -> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)])
-> Int
-> [(Text, uid1)]
-> [(Text, uid2)]
-> Scorer
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
oneShot QuickSearch uid2
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)]
forall uid.
(Hashable uid, Eq uid) =>
QuickSearch uid
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid)]
topNMatches
oneShotMatchesWithThreshold
    :: (Hashable uid1, Eq uid1, Hashable uid2, Eq uid2)
    => Int  
    -> [(T.Text, uid1)]  
    -> [(T.Text, uid2)]  
    -> Scorer  
    -> [(Entry T.Text uid1, [Match Score (Entry T.Text uid2)])]
  
oneShotMatchesWithThreshold :: Int
-> [(Text, uid1)]
-> [(Text, uid2)]
-> Scorer
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
oneShotMatchesWithThreshold = (QuickSearch uid2
 -> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)])
-> Int
-> [(Text, uid1)]
-> [(Text, uid2)]
-> Scorer
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
forall uid1 uid2.
(Hashable uid1, Eq uid1, Hashable uid2, Eq uid2) =>
(QuickSearch uid2
 -> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)])
-> Int
-> [(Text, uid1)]
-> [(Text, uid2)]
-> Scorer
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
oneShot QuickSearch uid2
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)]
forall uid.
(Hashable uid, Eq uid) =>
QuickSearch uid
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid)]
matchesWithThreshold