id,summary,reporter,owner,description,type,status,priority,milestone,component,version,resolution,keywords,cc,os,architecture,failure,difficulty,testcase,blockedby,blocking,related
3819,keeping RelaxedPolyRec as optional feature can help spotting infinite recursion,guest,,"This is a ticket you have nothing to do about - isn't this great?
I just want to give a real-world case where the current behaviour helped me to detect an infinite recursion early.

I wrote the following code, that implements a {{{poke}}} for any {{{Traversable}}} container with {{{Storable}}} elements:
{{{
   poke ::
      (Fold.Foldable f, Storable a) =>
      Ptr (f a) -> f a -> IO ()
   poke ptr x =
      evalStateT (Fold.traverse_ pokeState x) $
      castPtr ptr

   pokeState ::
      (Storable a) =>
      a -> StateT (Ptr a) IO ()
   pokeState x = do
      liftIO . flip poke x =<< get
      modify (flip advancePtr 1)
}}}

You can find this code here:
  http://code.haskell.org/~thielema/storable-record/src/Foreign/Storable/Traversable.hs

When I compiled this I got the compiler error:
{{{
   src/Foreign/Storable/Traversable.hs:67:0:
       Contexts differ in length
         (Use -XRelaxedPolyRec to allow this)
       When matching the contexts of the signatures for
         poke :: forall (f :: * -> *) a.
                 (Fold.Foldable f, Storable a) =>
                 Ptr (f a) -> f a -> IO ()
         pokeState :: forall a. (Storable a) => a -> StateT (Ptr a) IO ()
       The signature contexts in a mutually recursive group should all be identical
       When generalising the type(s) for poke, pokeState
}}}
This quickly pointed me to the problem, that the call to {{{poke}}} in {{{pokeState}}} actually was wrong. It must be {{{Storable.poke}}}. If GHC had compiled this, it would have certainly gone into an infinite recursion.

There are two ways to treat this example:
* Blame my naming style where I re-use common identifiers and distinguish them later by qualification.
* Count it as vote for keeping the RelaxedPolyRec as optional feature.
",proposal,closed,normal,,Compiler (Type checker),6.12.1,fixed,,ghc@…,Unknown/Multiple,Unknown/Multiple,None/Unknown,,,,,
