使用 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
,[()]
被丢弃并被替换为 ()
.
我尝试使用 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
,[()]
被丢弃并被替换为 ()
.