[GHC] #13881: Inexplicable error message when using out-of-scope type variable in pattern type signature
GHC
ghc-devs at haskell.org
Wed Jun 28 21:07:03 UTC 2017
#13881: Inexplicable error message when using out-of-scope type variable in pattern
type signature
-------------------------------------+-------------------------------------
Reporter: RyanGlScott | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler (Type | Version: 8.0.1
checker) |
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: Poor/confusing | Unknown/Multiple
error message | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by RyanGlScott):
I attempted to debug this a bit. I at least know why the error message is
happening. In an attempt to detect type variables that are manufactured
out of thin air in pattern signatures, such as this:
{{{#!hs
type T a = Int
f :: Int -> Int
f (x :: T a) = ...
}}}
GHC first collects the tyvars of the pattern signature, then collects the
//exact// tyvars (read: after type synonym expansion) of the typechecked
pattern signature, and if any tyvars from the first set aren't in the
second set, it errors. Seems simple enough.
Here's what I don't get though. Surprisingly, this variant of the program
compiles, even with `ScopedTypeVariables`:
{{{#!hs
fl :: forall (l :: [a]). Sing l -> Sing l
fl (SNil :: Sing (song :: [a])) = (SNil :: Sing l) :: Sing song
fl (SCons x xs) = SCons x xs
}}}
Here, the pattern signature for `SNil` //binds// the tyvar `song`, and
type inference figures out that it's equal to `l`. As a result, everything
works out.
But in the original variant of the program:
{{{#!hs
fl :: forall (l :: [a]). Sing l -> Sing l
fl (SNil :: Sing (l :: [y])) = SNil
fl (SCons x xs) = SCons x xs
}}}
Due to `ScopedTypeVariables`, the pattern signature is not binding `l`.
Therefore, after typechecking the pattern signature `l :: [y]` becomes `l
:: [a]`, since `a` is the kind variable we used when quantifying `l` in
the type signature for `fl`. But this presents a problem, because:
1. The kind vars of the original pattern signature include `y`
2. The exact kind vars of the typechecked pattern signature do //not//
include `y` (only `a`)
Thus, GHC errors.
I'm still not sure of the best way to inform GHC that `y` isn't bound by a
type synonym, however...
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13881#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list