#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