抛出异常w /`forever`?

时间:2016-05-20 03:15:10

标签: haskell

查看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

1 个答案:

答案 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中我们有一个实际的无限循环,一个意味着什么。