为什么`print <$>(print“ hello”)`打印“ hello”?

时间:2019-10-21 11:10:31

标签: haskell

在计算IO (IO ())时,会同时计算(IO ())(),所以为什么

main :: IO (IO ())
main = print <$> (print "Hello, World!")

打印

"Hello, World!"

不是

IO "Hello, World!" -- ??
"Hello, World!"

1 个答案:

答案 0 :(得分:21)

main :: IO (IO ())
main = print <$> (print "Hello, World!")
由于单子法则,

等同于

main :: IO (IO ())
main = do 
   result <- print "Hello, World!"
   return (print result)

现在,print始终返回()作为结果,因此整个代码等效于

main :: IO (IO ())
main = do 
   _ <- print "Hello, World!"
   return (print ())

最后,main的结果将被简单地丢弃。也就是说,最后一行可能是return (putStrLn "this is ignored"),并且效果相同。

因此,代码将仅执行第一个print "Hello, World!"

我建议您始终定义main :: IO ()。 Haskell允许我们声明main :: IO AnyTypeHere,但这(IMO)令人困惑。

我还建议您使用putStrLn而不是print来打印字符串,因为后者将引用并转义整个字符串。