在学习单子时,我经常遇到评估问题。我现在理解了惰性评估的基本概念,但我不知道Haskell中单子如何进行惰性评估。
考虑以下代码
module Main where
import Control.Monad
import Control.Applicative
import System
main = print <$> head <$> getArgs
在我看来,主要函数应该打印第一个控制台参数,但它没有打印出来。
我知道
getArgs :: IO [String]
head <$> getArgs :: IO String
print <$> (head <$> getArgs) :: IO (IO ())
main :: IO (IO ())
显然,第一个参数没有被打印到标准输出中,因为第一个IO单子的内容没有被评估。所以如果我将这两个单子合并,它就可以工作了。
main = join $ print <$> head <$> getArgs
有人可以为我澄清一下吗?(或者给我一个指示)
head <$> getArgs
,然后将其结果提供给return . print
,它的类型为a -> IO (IO ())
。 - Mikhail Glushenkovhead
没有被评估,因为它的结果不需要,所以你的代码永远不会产生“空列表”异常。你可以通过将getArgs
更改为getLine
来测试这一点。 - Mikhail Glushenkov