[Haskell-cafe] an evil type hangs GHC

wren ng thornton wren at freegeek.org
Fri Nov 12 18:43:08 EST 2010


On 11/12/10 4:53 PM, Ryan Ingram wrote:
>> From http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/bugs.html#bugs-ghc:
>
> GHC's inliner can be persuaded into non-termination using the standard
> way to encode recursion via a data type:

More specifically, since your bad2 does not look recursive, the inliner 
will get inline happy and apply the definition of bad1, but then it'll 
see a constant case match that it can reduce statically, and <loop>


{ okay, let's start with bad1 }

     bad1 b@(C f) = f b

{ mmm, tasty tasty sugar }

     bad1 = \b -> case b of C f -> f b

{ ha, dare you to optimize that further }

{ okay, now let's co compile bad2 }

     bad2 = bad1 (C bad1)

{ oh look, it's nonrecursive so let's start inlining }

     bad2 = (\b -> case b of C f -> f b) (C bad1)

{ oh look, an application we can evaluate statically }

     bad2 = let b = (C bad1) in case b of C f -> f b

{ meh, let's ignore sharing for now }

     bad2 = case (C bad1) of C f -> f (C bad1)

{ oh look, a case analysis we can evaluate statically }

     bad2 = let f = bad1 in f (C bad1)

{ oh look, f is only used once so we can substitute the let }
{ and if we didn't ignore sharing before, then we'd see that b is only 
used once now, so we could substitute that let too }

     bad2 = bad1 (C bad1)

{ oh look, it's nonrecursive so let's start inlining }

-- 
Live well,
~wren


More information about the Haskell-Cafe mailing list