使用 mapM_ / putStrLn 打印地图函数的输出列表

Print map function's output list using mapM_ / putStrLn

我尝试使用 putStrLn 打印 map 函数的列表输出,

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

它解决了问题,但是在这种情况下带有下划线后缀的 map monad 如何工作?

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[()] 被丢弃并被替换为 ().