我有一个具有以下结构的地图数据结构: - “英国的首都是什么” - > “伦敦” “法国的首都是什么” - > “巴黎” 我想循环显示这个问题的地图:“英国的首都是什么”,要求用户输入。如果用户回答“伦敦”,我打印正确,否则,我打印正确答案“伦敦”。在像C#这样的命令式语言中这很容易,但我还没想到如何在Haskell中这样做。
答案 0 :(得分:7)
以这种方式使用Map
的问题是很多遍历Map
值的遍历假设您不关心密钥而只关心包含的值。 Data.Map
内部的遍历就足够了,而且@danidiaz已经指出了,但是调用toList
是完全合理的,因为该列表将被懒惰地生成,而不是一次强制进入内存。给定一个元组列表(键,值),您可以使用for
或mapM
或fmap
或....基本上任何您喜欢的结构遍历,只要您可以使用IO monad。
{-# LANGUAGE OverloadedLists #-}
import Data.Foldable (for_)
import Data.Map (Map,toList)
m :: Map String String
m = [("a","1"),("b","2")]
main =
for_ (toList m) $ \(q,a) ->
do putStrLn q
x <- getLine
putStrLn (if x == a
then "Yes"
else "No: " ++ a)
编辑:我觉得有必要使用mapM_
添加大多数人称之为更惯用的Haskell的内容:
main :: IO ()
main = mapM_ ask (toList m)
ask :: (String,String) -> IO ()
ask (q,a) = do putStrLn q
x <- getLine
putStrLn (if x == a then "Yes" else "No: " ++ a)
答案 1 :(得分:2)
lens
的{{3}}允许您编写@ ThomasM.DuBuisson的代码而无需通过toList
。遍历函数在每次迭代时都可以访问索引。
main = ifor_ m $ \(q, a) -> do
putStrLn q
x <- getLine
putStrLn (if x == a then "Yes" else "No: " ++ a)