phoneBook =
[("betty", "555-2938"),
("honnie", "555-2222"),
("party", "333-1111"),
("hyper", "999-3838"),
("wendy", "222-1212"),
("penny", "888-8888")]
findKey :: (Eq k) => k -> [(k, v)] -> v
findKey key xs = snd . head . filter (\(k, v) -> key == k) $ xs
*Main> phoneBook
[("betty","555-2938"),("honnie","555-2222"),("party","333-1111"),("hyper","999-3838"),("wendy","222-1212"),("penny","888-8888")]
*Main> findKey "wendy" phoneBook
"222-1212"
*Main> findKey "thudy" phoneBook
"*** Exception: Prelude.head: empty list
findKey' :: (Eq k) => k -> [(k, v)] -> Maybe v
findKey' key [] = Nothing
findKey' key ((k,v):xs)
| key == k = Just v
| otherwise = findKey' key xs
*Main> findKey' "thudy" phoneBook
Nothing
*Main> findKey' "wendy" phoneBook
Just "222-1212"
phoneBook2 :: Map.Map String String
phoneBook2 = Map.fromList $
[("betty", "555-2938"),
("honnie", "555-2222"),
("party", "333-1111"),
("hyper", "999-3838"),
("wendy", "222-1212"),
("penny", "888-8888")]
# 連想リストをMapに変換する
*Main> Map.fromList [(3,"shoes"),(4,"trees"),(9,"bees")]
fromList [(3,"shoes"),(4,"trees"),(9,"bees")]
*Main> Map.fromList [("kima","greggs"),("jimmy","mcnulty"),("jay","landsman")]
fromList [("jay","landsman"),("jimmy","mcnulty"),("kima","greggs")]
# fromListだと、キーが重複するなら最後のだけを残す
*Main> Map.fromList [("MS",1),("MS",2),("MS",3)]
fromList [("MS",3)]
*Main> :t Map.fromList
Map.fromList :: Ord k => [(k, a)] -> Map.Map k a
# 連想リストからMapに変換すると、findKeyと同様の機能がlookupで使える
*Main> :t Map.lookup
Map.lookup :: Ord k => k -> Map.Map k a -> Maybe a
*Main> Map.lookup "wendy" phoneBook2
Just "222-1212"
*Main> Map.lookup "thudy" phoneBook2
Nothing
# 挿入
*Main> :t Map.insert
Map.insert :: Ord k => k -> a -> Map.Map k a -> Map.Map k a
*Main> let newBook = Map.insert "thudy" "888-9999" phoneBook2
*Main> Map.lookup "thudy" newBook
Just "888-9999"
*Main> newBook
fromList [("betty","555-2938"),("honnie","555-2222"),("hyper","999-3838"),("party","333-1111"),("penny","888-8888"),("thudy","888-9999"),("wendy","222-1212")]
string2digits :: String -> [Int]
string2digits = map digitToInt . filter isDigit
*Main> string2digits "888-8888"
[8,8,8,8,8,8,8]
*Main> let intBook = Map.map string2digits phoneBook'
*Main> let intBook = Map.map string2digits phoneBook2
let intBook = Map.map string2digits phoneBook2
*Main> Map.lookup "wendy" intBook
Just [2,2,2,1,2,1,2]
phoneBook3 =
[("betty", "555-2938"),
("betty", "555-9999"),
("honnie", "555-2222"),
("party", "333-1111"),
("party", "333-2222"),
("hyper", "999-3838"),
("wendy", "222-1212"),
("wendy", "888-8888"),
("penny", "888-9999")]
phoneBookToMap :: (Ord k) => [(k, String)] -> Map.Map k String
phoneBookToMap xs = Map.fromListWith add xs
where add number1 number2 = number1 ++ ", " ++ number2
phoneBookToMap' :: (Ord k) => [(k,a)] -> Map.Map k [a]
phoneBookToMap' xs = Map.fromListWith (++) $ map (\(k, v) -> (k, [v])) xs
*Main> Map.lookup "wendy" $ phoneBookToMap phoneBook3
Just "888-8888, 222-1212"
*Main> Map.lookup "wendy" $ phoneBookToMap' phoneBook3
Just ["888-8888","222-1212"]