在GHCi中let y = y + 1
编译得很好,但是当我尝试评估时,我得到了*** Exception: <<loop>>
为什么没有编译错误,它是什么意思<<loop>>
?
答案 0 :(得分:25)
Haskell let
,where
和顶级绑定默认递归,即使它们不是函数。因此let y = y + 1
定义了向数字添加1
的无限循环。 GHC用<<loop>>
异常表示这样的循环 - 当然它可以捕获它们!
这可用于延迟操作,因为它允许我们轻松定义诸如无限列表(let xs = 0:xs
)之类的东西,这些列表定义明确且对普通代码实际上很有用。但是,它不适用于+
等严格操作(对于大多数数字类型),因为它们需要立即评估整个(无限)事物。
答案 1 :(得分:0)
我想添加一个可能实际有用的最小示例。
data Peano = Z | S Peano
instance Num Peano where
p + Z = p
p + (S q) = S (p + q)
fromInteger 1 = S Z
instance Eq Peano where
Z == Z = True
Z == _ = False
_ == Z = False
(S p) == (S q) = p == q
instance Ord Peano where
Z `compare` Z = EQ
Z `compare` _ = LT
_ `compare` Z = GT
(S p) `compare` (S q) = p `compare` q
y :: Peano
y = y + 1
main :: IO ()
main = print $ 1 < y
在这种情况下,y
是无穷大,直到同构。 (尽管我的fromInteger
显然是一个糟糕的实现,因此将文字1
更改为其他内容而不修复fromInteger
将会失败。)
请注意,这只有效,因为我定义的(+)
在其第一个参数中是懒惰的,而我定义的compare
也是懒惰的。< / p>