使用严格注释将GHC引入无限循环

rem*_*rem 4 haskell

出于某种原因,我需要欺骗Haskell执行一个无限循环,而不是仅仅检测它并退出<<loop>>,但它太聪明了.是否有任何方便的例子,其中循环是由严格注释(!)引起的,还是我可以关闭循环检测?目前我在做

x = x + y
y = x + y
inf !n = 0

main = do
    print $ inf x
Run Code Online (Sandbox Code Playgroud)

GS *_*ica 10

这应该这样做:

{-# LANGUAGE BangPatterns #-}
f :: Int -> Int
f x = if x >= 0 then f (x + 1) else 0

fun !n = 0

main = print $ fun $ f 0
Run Code Online (Sandbox Code Playgroud)

在我添加if它之前,GHC确实似乎非常聪明地发现循环,甚至发现了递归函数调用.

-O3在GHC 7.10上测试了这个.

编辑:添加了fun提问者建议的额外功能,只是为了满足涉及爆炸模式的要求.它与循环本身并不真正相关.此外,从改变IntegerInt另一个答案的建议,以确保持续的内存使用情况.


use*_*445 6

"问题"是当ghc正在评估thunk时,它会用黑洞替换它.这就是为什么类似以下简单示例的东西不起作用的原因:

inf :: ()
inf = inf

main :: IO ()
main = return $! inf
Run Code Online (Sandbox Code Playgroud)

Ghc将强制inf,这将导致它第二次强制inf.它将实现inf被黑洞并检测到一个循环.

提出无限计数器的解决方案将起作用,但会为整数计数器分配越来越多的内存.它可能无关紧要,因为Integer的内存是对数的,但使用Int可能会稍微优雅,只需让计数器换行.

另一种选择是使用无限数据结构.这将创建垃圾,但在稳定状态下消耗固定数量的已分配内存.就像是:

main :: IO ()
main = return $! last $ repeat ()
Run Code Online (Sandbox Code Playgroud)