使用mapM_ / putStrLn打印地图功能的输出列表

时间:2015-06-30 01:43:32

标签: haskell monads

我尝试使用putStrLn as,

打印地图功能的列表输出
main = do
  let out = "hello\nworld\nbye\nworld\n"
  putStrLn $ map ("out: " ++) $ lines out

它抛出错误,

Couldn't match type ‘[Char]’ with ‘Char’

我提到了其他一些代码并将最后一行更改为

  mapM_ putStrLn $ map ("out: " ++) $ lines out

它解决了这个问题,但是在这种情况下如何使用下划线后缀映射monad?

1 个答案:

答案 0 :(得分:4)

mapM_基于mapM函数,其类型为

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

mapM_的类型为

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

对于前者,它在列表上的行为与普通map相似,但每个元素都有一个动作运行,结果汇总。因此,例如,如果您想要读取多个文件,则可以使用contents <- mapM readFile [filename1, filename2, filename3]contents将是一个列表,其中每个元素表示相应文件的内容。 mapM_函数执行相同的操作,但会丢弃结果。一个定义是

mapM_ f list = do
    mapM f list
    return ()

每个操作都会执行,但不会返回任何内容。这在像你这样结果值无效的情况下很有用,即()是类型()的唯一值,因此无法从中做出实际决策。如果您有mapM putStrLn someListOfStrings,那么结果会有IO [()]类型,但mapM_ putStrLn someListOfStrings [()]会被删除,只会被()替换。