GHC在编译时崩溃

时间:2014-03-02 04:06:54

标签: haskell ghc

module Main where

newtype Rec a b = Rec {deRec :: Rec a b -> a}

infixl 1 >|>
infixl 1 <|<
(>|>) = Rec
(<|<) (Rec x) = x

fix f = (\x -> f (x <|< x)) (Rec (\x -> f (x <|< x)))
factorial = fix (\f x -> if x<=1 then 1 else x*f(x-1))

main = do 
   x <- getLine
   putStrLn (show (factorial (read x)))

GHC回应:

ghc: panic! (the 'impossible' happened)
  (GHC version 7.6.3 for x86_64-apple-darwin):
    Simplifier ticks exhausted
    When trying UnfoldingDone a_sMx{v} [lid]
    To increase the limit, use -fsimpl-tick-factor=N (default 100)
    If you need to do this, let GHC HQ know, and what factor you needed
    To see detailed counts use -ddump-simpl-stats
    Total ticks: 7121

Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug

出了什么问题?

2 个答案:

答案 0 :(得分:13)

我认为这与已知错误有关。请参阅ghc手册的第14.2节:

http://www.haskell.org/ghc/docs/7.6.2/html/users_guide/bugs.html

我将在此重现相关部分:

  

GHC的内联器可以使用标准方式通过数据类型编码递归来说服非终止:

data U = MkU (U -> Bool)

russel :: U -> Bool
russel u@(MkU p) = not $ p u

x :: Bool
x = russel (MkU russel)
  

我们从来没有发现过另一类程序,除了这个程序之外,它使GHC发散,修复问题会给每次编译带来额外的开销。所以bug仍然是不固定的。 Secrets of the GHC inliner中有更多背景信息。

换句话说,当您在负位置(即函数的参数)使用递归时会出现此错误。从手册中可以看出,他们无意解决这个问题。

答案 1 :(得分:1)

如前所述,当GHC的内联使用具有递归类型参数的函数时,会出现问题。这可以与NOINLINE pragma一起使用。在你的情况下:

{-# NOINLINE (<|<) #-}