#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
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs