@@ -1,86 +1,35 @@
1{-# OPTIONS_GHC -Wall #-}
1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Suggest
3module Reporting.Suggest
4− ( findPotentialTypos, findTypoPairs, vetTypos
4+ ( distance
5− , nearbyNames, distance
5+ , sort
10−import Data.Function (on)
10+import qualified Data.Char as Char
11import qualified Data.List as List
11import qualified Data.List as List
12−import qualified Data.Map as Map
13−import qualified Data.Maybe as Maybe
14−import qualified Data.Set as Set
15import qualified Text.EditDistance as Dist
12import qualified Text.EditDistance as Dist
19−-- FIND TYPOS
16+-- DISTANCE
22−findPotentialTypos :: [String] -> String -> [String]
23−findPotentialTypos knownNames badName =
24− filter (\name -> distance badName name == 1) knownNames
27−findTypoPairs :: [String] -> [String] -> [(String, String)]
28−findTypoPairs leftOnly rightOnly =
31− map ((,) leftName) (findPotentialTypos rightOnly leftName)
33− concatMap veryNear leftOnly
36−vetTypos :: [(String, String)] -> Maybe (Set.Set String, Set.Set String)
37−vetTypos potentialTypos =
39− tallyNames (ln, rn) (lc, rc) =
40− ( Map.insertWith (+) ln 1 lc
41− , Map.insertWith (+) rn 1 rc
44− (leftCounts, rightCounts) =
45− foldr tallyNames (Map.empty, Map.empty) potentialTypos
47− acceptable :: Map.Map String Int -> Bool
49− not (Map.null counts)
51− Map.foldr (\n unique -> n < 2 && unique) True counts
53− if acceptable leftCounts && acceptable rightCounts then
54− Just (Map.keysSet leftCounts, Map.keysSet rightCounts)
19+distance :: String -> String -> Int
21+ Dist.restrictedDamerauLevenshteinDistance Dist.defaultEditCosts x y
64−nearbyNames :: (a -> String) -> a -> [a] -> [a]
25+-- SORT
65−nearbyNames toString value possibleValues =
71− if length name < 3 then 1 else 2
73− getDistance pValue =
28+sort :: String -> (a -> String) -> [a] -> [a]
74− let
29+sort target toString values =
75− dist = abs (distance name (toString pValue))
30+ List.sortOn (distance (toLower target) . toLower . toString) values
77− if dist <= editDistance then Just (dist, pValue) else Nothing
80− List.sortBy (compare `on` fst) $
81− Maybe.mapMaybe getDistance possibleValues
84−distance :: String -> String -> Int
33+toLower :: String -> String
85−distance x y =
34+toLower string =
86− Dist.restrictedDamerauLevenshteinDistance Dist.defaultEditCosts x y
35+ map Char.toLower string