-
Notifications
You must be signed in to change notification settings - Fork 0
/
Utils.hs
48 lines (41 loc) · 1.79 KB
/
Utils.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
module Utils (
textToInt,
keyValuesToMap,
counter,
printd
) where
import qualified Data.Map as M
import qualified Data.Text as T
import qualified Data.Text.IO as TextIO
import Data.List (groupBy, sort)
textToInt :: T.Text -> Int
textToInt = read . T.unpack
-- Converts a list of key/values into a map, aggregating values
-- e.g. [(1, "one"), (2, "two"), (1, "uno")] -> Map {1: ["one", "uno"], 2: ["two"]}
keyValuesToMap :: (Eq k, Ord k, Ord v) => [(k, v)] -> M.Map k [v]
keyValuesToMap = M.fromList . groupValues
where
groupValues :: (Eq k, Ord k, Ord v) => [(k, v)] -> [(k, [v])]
groupValues = map foldValues . groupBy (\(x, _) (y, _) -> x == y) . sort
-- Combines values of the same key into a list
-- e.g. [(1, 2), (1, 4), (1, 5)] -> (1, [2, 4, 5])
-- Precondition: the key must be the same for all values in the input list
foldValues :: (Eq k, Ord k, Ord v) => [(k, v)] -> (k, [v])
foldValues xs = foldr accumulateSameKeyValues (key, []) xs
where
key = fst . head $ xs
accumulateSameKeyValues :: (Eq k, Ord k, Ord v) => (k, v) -> (k, [v]) -> (k, [v])
accumulateSameKeyValues (key1, value) (key2, values)
| key1 == key2 = (key1, value:values)
| otherwise = error "Cannot group values for different keys."
-- Counts number of same elements in a list, e.g.
-- [1, 3, 1, 5, 3, 1] -> Map {1: 3, 3: 2, 5: 1}
counter :: (Eq k, Ord k) => [k] -> M.Map k Int
counter = M.fromList . count where
count :: (Eq k, Ord k) => [k] -> [(k, Int)]
count = map (\xs -> (head xs, length xs)) . groupBy (==) . sort
printd :: (Show a) => String -> a -> IO ()
printd label value = do
putStrLn label
putStrLn $ show value
putStrLn ""