Haskell mapM putStrLn[“a”和“b”为什么显示三行?

Haskell mapM putStrLn[“a”和“b”为什么显示三行?,haskell,io,monads,Haskell,Io,Monads,为什么第一个版本显示第三行,第二个版本显示第三行,第三行来自哪里。我没想到会这样。如果你把mapM版本放在一个独立的程序中,用ghc编译并运行它,你也不会得到第三行: Prelude> mapM putStrLn ["a", "b"] a b [(),()] Prelude> mapM_ putStrLn ["a", "b"] a b 您在ghci中看到的[(),()]只是mapM调用的返回值ghci自动显示您输入的每个表达式的值。(这就是为什么ghci被称为读取-计算-打印循环,

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

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

Prelude> mapM putStrLn ["a", "b"]
a
b
[(),()]
Prelude> mapM_ putStrLn ["a", "b"]
a
b
您在
ghci
中看到的
[(),()]
只是
mapM
调用的返回值<代码>ghci自动显示您输入的每个表达式的值。(这就是为什么
ghci
被称为读取-计算-打印循环,或REPL;“打印”部分就是您在这里看到的。)

mapM
创建一个包含每个
putStrLn
调用的返回值的列表时(因此列表中的每个元素都有一个
()
),
mapM\uu
丢弃这些返回值并返回
IO()
,而
ghci
不需要显示。因此,在这种情况下,您看不到来自
ghci
的额外行。

实际上,mapM_uu返回IO(),但ghci不需要打印()。
$ cat demo.hs
main = mapM putStrLn [ "a", "b" ]
$ ghc demo.hs
$ ./demo
a
b
$