#7288: type inference fails with where clause (RankNTypes, TypeFamilies)
----------------------------------------+-----------------------------------
  Reporter:  agrafix                    |          Owner:                       
                   
      Type:  bug                        |         Status:  closed               
                   
  Priority:  normal                     |      Milestone:                       
                   
 Component:  Compiler (Type checker)    |        Version:  7.6.1                
                   
Resolution:  invalid                    |       Keywords:  type inference, 
rankntypes, typefamilies
        Os:  Unknown/Multiple           |   Architecture:  Unknown/Multiple     
                   
   Failure:  GHC rejects valid program  |     Difficulty:  Unknown              
                   
  Testcase:                             |      Blockedby:                       
                   
  Blocking:                             |        Related:                       
                   
----------------------------------------+-----------------------------------

Comment(by dleuschner):

 Thanks, Simon!  I guess it looked like it was a let vs. where issue
 because the indentation suggests that the where-clause is inside the scope
 of the lambda but it isn't.  It would be nice if lambdas could have where
 bindings. :-)

 Replying to [comment:2 simonpj]:
 > Well, I'm afraid this is by design.
 >
 > With `TypeFamilies`, local let or where bindings are not generalised;
 see Section 4.2 of the
 [http://www.haskell.org/haskellwiki/Simonpj/Talk:OutsideIn OutsideIn
 paper].  So,
 >
 >  * In `myGen''` you give a type signature; and indeed `patToStruct` has
 the type you specify.
 >
 >  * In `mkGen'` the `let` is not generalised, but it's fine because it's
 only called at one type.
 >
 >  * In `mkGen`, the `where` is not generalised, and this time it does
 matter, because the (monomorphic) `patToStruct` is outside the `(\pid ->
 ...)`, which itself is specified to have the polymorphic type `GenFun Int
 [Struct]`.  So there is a skolem-escape problem:
 > {{{
 > T7288.hs:30:28:
 >     Couldn't match type `m0' with `m'
 >       because type variable `m' would escape its scope
 >     This (rigid, skolem) type variable is bound by
 >       a type expected by the context: GenM m => Int -> m [Struct]
 >       at T7288.hs:(28,5)-(31,25)
 >     Expected type: Int -> m Struct
 >       Actual type: Int -> m0 Struct
 >     Relevant bindings include
 >       patToStruct :: Int -> m0 Struct (bound at T7288.hs:33:11)
 >     In the first argument of `mapM', namely `patToStruct'
 >     In a stmt of a 'do' block: structs <- mapM patToStruct pats
 >     In the expression:
 >       do { pats <- getPatients;
 >            structs <- mapM patToStruct pats;
 >            return structs }
 > }}}
 >
 > It's not a `let` vs `where` issue; the question is whether the non-
 generalised binding is outside the expression with a forall'd type.
 >
 > You can change the behaviour by adding `NoMonoLocalBinds` (after
 `TypeFamilies`) as a LANGUAGE pragma.  Then GHC tries harder, but less
 robustly and predictably.
 >
 > I wish I knew a better solution, but currently I don't.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7288#comment:3>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler

_______________________________________________
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to