Haskell 哈斯克尔:可以';t使用;地图putStrLn";?

Haskell 哈斯克尔:可以';t使用;地图putStrLn";?,haskell,io,monads,Haskell,Io,Monads,我有一个字符串列表,并尝试了以下操作: 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: m

我有一个字符串列表,并尝试了以下操作:

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),则打印并递归)。但只使用地图会简单得多


谢谢

函数的类型应为
IO t
(其中
t
是一个类型变量)。
map putStrLn ls
的类型是
[IO()]
。这就是您收到此错误消息的原因。您可以通过在
ghci
中运行以下命令来验证这一点:

Prelude> :type map putStrLn ls
map putStrLn ls :: [IO ()]
解决这个问题的一个方法是使用,这是
map
的“一元”版本。或者,您可以使用与
mapM
相同的函数,但不从函数中收集返回值。由于您不关心
putStrLn
的返回值,因此更适合在此处使用
mapM
mapM
具有以下类型:

mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
以下是如何使用它:

ls = [ "banana", "mango", "orange" ]
main = mapM_ putStrLn ls

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

,我希望我能早点学到的是Data.Traversable中定义了另一个mapM。这个mapM除了使用列表之外,还可以使用更多的数据结构,比如地图和数组。我一直认为
main
应该是
IO()
类型,我从来都不知道它可能是
。IO t
。这显示了你如何每天学习新东西:-)我有一个
IO字符串
,我想把它映射到
IO Int
并打印
Int
。我如何在一行中完成它?那有可能吗。