[GHC] #14570: Untouchable error arises from type equality, but not equivalent program with fundeps
GHC
ghc-devs at haskell.org
Sun Dec 10 17:39:56 UTC 2017
#14570: Untouchable error arises from type equality, but not equivalent program
with fundeps
-------------------------------------+-------------------------------------
Reporter: lexi.lambda | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 8.0.2
(Type checker) |
Keywords: | 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:
-------------------------------------+-------------------------------------
Given some type definitions:
{{{#!hs
data A
data B (f :: * -> *)
data X (k :: *)
}}}
…and this typeclass:
{{{#!hs
class C k a | k -> a
}}}
…these (highly contrived for the purposes of a minimal example) function
definitions typecheck:
{{{#!hs
f :: forall f. (forall k. (C k (B f)) => f k) -> A
f _ = undefined
g :: (forall k. (C k (B X)) => X k) -> A
g = f
}}}
However, if we use a type family instead of a class with a functional
dependency:
{{{#!hs
type family F (k :: *)
}}}
…then the equivalent function definitions fail to typecheck:
{{{#!hs
f :: forall f. (forall k. (F k ~ B f) => f k) -> A
f _ = undefined
g :: (forall k. (F k ~ B X) => X k) -> A
g = f
}}}
{{{
• Couldn't match type ‘f0’ with ‘X’
‘f0’ is untouchable
inside the constraints: F k ~ B f0
bound by a type expected by the context:
F k ~ B f0 => f0 k
Expected type: f0 k
Actual type: X k
• In the expression: f
In an equation for ‘g’: g = f
}}}
I read Section 5.2 of the OutsideIn(X) paper, which describes touchable
and untouchable type variables, and I ''sort of'' understand what’s going
on here. If I add an extra argument to `f` that pushes the choice of `f`
outside the inner `forall`, then the program typechecks:
{{{#!hs
f :: forall f a. f a -> (forall k. (F k ~ B f) => f k) -> A
f _ _ = undefined
g :: forall a. X a -> (forall k. (F k ~ B X) => X k) -> A
g = f
}}}
I don’t know if this is actually a bug—it seems entirely reasonable to me
that I don’t fully understand what is going on here—but I’m stumped as to
''why'' GHC rejects this program but accepts the one involving functional
dependencies. I would expect it to either accept or reject both programs,
given they ''seem'' equivalent.
Is this just an unfortunate infelicity of the differences between how
functional dependencies and type equalities are internally solved? Or is
there a deeper difference between these two programs?
,,(Note: This ticket is adapted from
[https://stackoverflow.com/q/47734825/465378 this Stack Overflow
question].),,
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14570>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list