我有一个字符串列表,并尝试了这个:
ls = [ "banana", "mango", "orange" ]
main = do
map PutStrLn list_of_strings
那不起作用,我无法理解为什么。
ghc print-list.hs
print-list.hs:3:0:
Couldn't match expected type `IO t' against inferred type `[IO ()]'
In the expression: main
When checking the type of the function `main'
任何提示?我想它与地图返回列表而不是值有关,但我找不到一种简单的方法来解决这个问题。
现在,我知道打印字符串列表的唯一方法是编写一个函数来迭代列表,打印每个元素(如果列表是[a]则打印,但打印并递归如果它是(a:b) ))。但是使用map ...
会更简单谢谢!
答案 0 :(得分:93)
main
函数的类型应为IO t
(其中t
是一个类型变量)。 map putStrLn ls
的类型为[IO ()]
。这就是您收到此错误消息的原因。您可以通过在ghci
中运行以下内容来自行验证:
Prelude> :type map putStrLn ls
map putStrLn ls :: [IO ()]
问题的一个解决方案是使用mapM
,这是map
的“monadic”版本。或者,您可以使用与mapM
相同的mapM_
,但不会从函数中收集返回的值。由于您不关心putStrLn
的返回值,因此在此处使用mapM_
更为合适。 mapM_
具有以下类型:
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
以下是如何使用它:
ls = [ "banana", "mango", "orange" ]
main = mapM_ putStrLn ls
答案 1 :(得分:20)
艾曼的回答对这种情况最有意义。一般情况下,如果您有[m ()]
并且想要m ()
,请使用sequence_
,其中m
可以是任何包含IO
的monad。