我现在正在学习哈斯克尔。我读到的定义>>是:
(>>) :: m a -> m b -> m b
x >> y = x >>= \_ -> y
Run Code Online (Sandbox Code Playgroud)
凉爽的。然而,如果x没有被使用并且 Haskell 很懒,为什么会打印“hi”?
ghci> print "hi" >> return "end"
"hi"
"end"
Run Code Online (Sandbox Code Playgroud)
由于懒惰,类似的构造仅返回“end”并且永远不会解析第一个参数:
ghci> skip _ r = r
ghci> skip (print "hi") "end"
"end"
Run Code Online (Sandbox Code Playgroud)
我明白这>>必须像现在这样工作,否则单子就会失去意义。但我不明白为什么它实际上有效。
您认为“x未使用”的假设是错误的。
的结果未被x使用,但其本身x被使用。这里的关键见解是,这x不是一个值本身,而是一种“配方”,执行时会产生一个值。令人困惑的是,这个“配方”本身也是一个类型的值IO a,但它与 的值不同a,后者是执行的结果x。
IO a这种“菜谱”的执行方式很神奇。基本上执行的唯一方法IO a是使其值为main- 程序入口点。然后 Haskell 运行时将在程序运行时执行该值。
价值main本身可以通过多种方式构建。一种方法可能是>>操作员。该运算符创建一个新IO a值,执行时将首先执行其左侧参数,然后执行其右侧参数。一个又一个地执行IO a价值观也是一种魔法。这个魔法隐藏在>>=操作符中。