循环遍历Haskell中的地图数据结构

时间:2017-03-02 20:33:01

标签: loops haskell dictionary

我有一个具有以下结构的地图数据结构: - “英国的首都是什么” - > “伦敦” “法国的首都是什么” - > “巴黎” 我想循环显示这个问题的地图:“英国的首都是什么”,要求用户输入。如果用户回答“伦敦”,我打印正确,否则,我打印正确答案“伦敦”。在像C#这样的命令式语言中这很容易,但我还没想到如何在Haskell中这样做。

2 个答案:

答案 0 :(得分:7)

以这种方式使用Map的问题是很多遍历Map值的遍历假设您不关心密钥而只关心包含的值。 Data.Map内部的遍历就足够了,而且@danidiaz已经指出了,但是调用toList是完全合理的,因为该列表将被懒惰地生成,而不是一次强制进入内存。给定一个元组列表(键,值),您可以使用formapMfmap或....基本上任何您喜欢的结构遍历,只要您可以使用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)