[GHC] #13549: GHC 8.2.1's typechecker rejects code generated by singletons that 8.0 accepts
GHC
ghc-devs at haskell.org
Sun Apr 23 03:05:02 UTC 2017
#13549: GHC 8.2.1's typechecker rejects code generated by singletons that 8.0
accepts
-------------------------------------+-------------------------------------
Reporter: RyanGlScott | Owner: (none)
Type: bug | Status: closed
Priority: normal | Milestone: 8.4.1
Component: Compiler (Type | Version: 8.1
checker) |
Resolution: duplicate | Keywords: TypeInType
Operating System: Unknown/Multiple | Architecture:
Type of failure: GHC rejects | Unknown/Multiple
valid program | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Changes (by goldfire):
* status: new => closed
* resolution: => duplicate
Comment:
I think I understand this now. This is a fundamental difference between
inference for types and inference for kinds.
Here is the original, unsingletonized code in question:
{{{#!hs
permutations :: [a] -> [[a]]
permutations xs0 = xs0 : perms xs0 []
where
-- perms :: forall a. [a] -> [a] -> [[a]]
perms [] _ = []
perms (t:ts) is = foldr interleave (perms ts (t:is)) (permutations is)
where -- interleave :: [a] -> [[a]] -> [[a]]
interleave xs r = let (_,zs) = interleave' id xs r in
zs
-- interleave' :: ([a] -> [a]) -> [a] -> [[a]] -> ([a],[[a]])
interleave' _ [] r = (ts, r)
interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:))
ys r
in (y:us, f (t:y:us) : zs)
}}}
Note that the local function signatures are commented out. This code
compiles, although if you uncomment the type signatures, you'd need
`ScopedTypeVariables`.
Let's consider type-checking this with `MonoLocalBinds` on (that is, "let
should not be generalized"). The body of `interleave'` mentions `t`, a
variable that's not local to `interleave'`. Thus, according to
`MonoLocalBinds`, its type should not be generalized. The problem is that
the type cannot be fully figured out solely by looking at the definition
of `interleave'`: by the time type inference is done with `interleave'`,
we know only that its type looks like `([a1] -> a2) -> [a1] -> [a2] ->
([a1], [a2])`. Later, we will learn that `a2` is really `[a1]`. This is
just fine for type inference, but it's bad for kind inference.
The problem is that when GHC sees a type signature `x :: ty`, it
interprets `ty` independent of any definition or usage of `x`. After
processing that statement, `ty` has been desugared and is set in stone --
including the kinds of any type variables in `ty`.
After singletonizing, the type of the singletonized version of
`interleave'` will mention the type family `Interleave'`, whose body is
just like that of `interleave'`. This type family's kind ''will'' mention
both `a1` and `a2`, as it has no reason not to. So `sInterleave'` would
also have to have a generalized kind for it all to work out. But with the
improvement in `decideKindGeneralisationPlan`, this doesn't happen.
So, here is the characterization of the infelicity in singletons: if a
local function's type would be different depending on the presence of
`MonoLocalBinds`, then it needs a type signature in order for singletons
to work. In the case of `interleave'`, without `MonoLocalBinds`, `a2` is
quantified over, leading to a different type than it would have otherwise.
(Note that the kind for the `Interleave'` type family is generalized,
regardless of `MonoLocalBinds`.)
I'm fairly confident in this analysis. I'm going to close the ticket as a
dup of #13555.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13549#comment:13>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list