查看forever
:
λ: import Control.Monad
λ: :t forever
forever :: Monad m => m a -> m b
为什么forever $ Just 42
会在几秒钟后抛出异常?
λ: forever $ Just 42
*** Exception: <<loop>>
然而forever $ return 4
没有(至少几秒钟后)?
λ: forever $ return 4
^C^C^C^Z
[1]+ Stopped ghci
答案 0 :(得分:1)
为了不详细说明实施细节(我并不完全熟悉),我将解释为什么这种行为是可取的以及它来自哪里。
forever
定义为
forever x = do
x
forever x
相当于
forever x = x >> forever x
所以,如果我们看一下
fr x = forever (return x)
我们有
fr x = forever (return x)
= return x >> forever (return x)
= return x >>= \_ -> fr x
= (\_ -> fr x) x
= fr x
所以,基本上,fr x
是一个无限循环。
现在在Haskell中,无限循环和错误是相同的。以下是error
:
error s = error s
现在,GHC选择区分这两种类型的循环。
纯代码中的无限循环是一个错误。一般来说,我们并不打算输入一个,我们正在寻找一个价值,而不是副作用。因此,在Maybe
中,无限循环以错误结束。
然而,纯代码中的无限循环很常见!代码可能正在等待机器,用户输入或其他事情发生的其他事情。
所以在IO
中我们有一个实际的无限循环,一个意味着什么。