#3819: keeping RelaxedPolyRec as optional feature can help spotting infinite
recursion
---------------------------------+------------------------------------------
    Reporter:  guest             |       Owner:                         
        Type:  proposal          |      Status:  new                    
    Priority:  normal            |   Component:  Compiler (Type checker)
     Version:  6.12.1            |    Keywords:                         
          Os:  Unknown/Multiple  |    Testcase:                         
Architecture:  Unknown/Multiple  |     Failure:  None/Unknown           
---------------------------------+------------------------------------------
 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.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/3819>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to