Prelude> mapM putStrLn ["a", "b"]
a
b
[(),()]
Prelude> mapM_ putStrLn ["a", "b"]
a
b

为什么第一个版本显示第三行而第二个没有,第三行来自哪里。我没想到。

最佳答案

如果你将 mapM 版本放在一个独立的程序中,用 ghc 编译它,然后运行它,你也不会从中得到第三行:

$ cat demo.hs
main = mapM putStrLn [ "a", "b" ]
$ ghc demo.hs
$ ./demo
a
b
$

你在 [(),()] 中看到的 ghci 只是 mapM 调用的返回值; ghci 自动显示您输入的每个表达式的值。 (这就是为什么 ghci 被称为读取-评估-打印循环,或 REPL;“打印”部分就是你在这里看到的。)

虽然 mapM 创建了一个包含每个 putStrLn 调用的返回值的列表(因此您为列表中的每个元素获得一个 ()),但 mapM_ 丢弃这些返回值并返回 IO ()ghci 不会显示。因此,在这种情况下,您不会从 ghci 中看到额外的一行。

10-06 10:16