我现在正在学习Haskell。我读到>>
的定义是:
(>>) :: m a -> m b -> m b
x >> y = x >>= \_ -> y
但是,如果没有使用x
,并且Haskell是懒惰的,那么为什么会打印“hi”?
ghci> print "hi" >> return "end"
"hi"
"end"
类似的构造只返回“end”,并且由于懒惰而从不解析第一个参数:
ghci> skip _ r = r
ghci> skip (print "hi") "end"
"end"
我知道>>
必须像现在这样工作,否则monads就会失去意义,但我不明白为什么它会工作。🤔
1条答案
按热度按时间pobjuy321#
您认为“
x
未被使用”的假设是错误的。x
的 result 没有被使用,但是x
本身被使用了。这里的关键是x
本身不是一个值,而是一个“配方”,当执行时,它将产生一个值。这个“配方”本身也是一个IO a
类型的值,但是它与a
的值不同。这将是执行x
的结果。这种“配方”
IO a
的执行方式是神奇的。基本上,执行IO a
的唯一方法是将其作为main
的值-程序入口点。然后Haskell运行时将在程序运行时执行该值。main
值本身可以用多种方式构造。一种方式可以是>>
运算符。该运算符创建一个新的IO a
值,该值在执行时将首先执行其左参数,然后执行其右参数。一个接一个地执行IO a
值也是魔术。这种魔术隐藏在>>=
运算符中。