64

我有一个字符串列表,并尝试了这个:

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'

有什么提示吗?我想这与 map 返回一个列表而不是一个值有关,但我没有找到一种简单的方法来解决这个问题。

现在我知道打印字符串列表的唯一方法是编写一个函数来迭代列表,打印每个元素(如果列表是 [a] 则打印,但如果它是 (a:b) 则打印并递归)。但是只使用地图会简单得多......

谢谢!

4

2 回答 2

109

函数的类型main应该是IO tt类型变量在哪里)。的类型map putStrLn ls[IO ()]。这就是您收到此错误消息的原因。您可以通过在中运行以下命令自己验证这一点ghci

Prelude> :type map putStrLn ls
map putStrLn ls :: [IO ()]

mapM该问题的一种解决方案是使用map. 或者你可以使用mapM_which 相同mapM但不收集函数的返回值。既然你不关心 的返回值putStrLn,这里用起来比较合适mapM_mapM_具有以下类型:

mapM_ :: Monad m => (a -> m b) -> [a] -> m ()

以下是如何使用它:

ls = [ "banana", "mango", "orange" ]
main = mapM_ putStrLn ls
于 2009-05-31T19:28:13.367 回答
23

艾曼的回答对这种情况最有意义。一般来说,如果你有[m ()]并且你想要m (),然后使用sequence_,其中m可以是任何单子,包括IO.

于 2009-05-31T19:32:48.597 回答