GHC: Ticket #1614: Type checker does not use functional dependency to avoid ambiguity
http://ghc.haskell.org/trac/ghc/ticket/1614
<p>
Compiling the following module gives an error
</p>
<pre class="wiki">module X where
class C a | -> a
instance C Int
unC :: (C a) => a -> Int
unC i = undefined
test :: Int
test = unC undefined
</pre><p>
Error message:
</p>
<pre class="wiki">X.hs:13:7:
Ambiguous type variable `a' in the constraint:
`C a' arising from a use of `unC' at X.hs:13:7-19
Probable fix: add a type signature that fixes these type variable(s)
</pre><p>
But that is just plain wrong. The functional dependency in the definition of C forces a to be Int. No other type is possible. So what's ambiguous about that?
</p>
en-usGHChttp://ghc.haskell.org/trac/ghc/chrome/site/ghc_logo.png
http://ghc.haskell.org/trac/ghc/ticket/1614
Trac 1.0.1iglooFri, 17 Aug 2007 19:40:21 GMTmilestone set
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:1
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:1
<ul>
<li><strong>milestone</strong>
set to <em>6.8</em>
</li>
</ul>
TicketsimonpjFri, 24 Aug 2007 08:13:57 GMT
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:2
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:2
<p>
This is a variant of <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/1624" title="bug: internal error caused by adding an instance to a type class with a ... (closed: fixed)">#1624</a>. Why didn't you write this?
</p>
<pre class="wiki">unC :: Int -> Int
</pre><p>
Do you have a real program in which this causes you a problem? Death to functional dependencies, say I.
</p>
<p>
Simon
</p>
TicketguestSat, 25 Aug 2007 10:59:18 GMT
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:3
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:3
<p>
What I'm really trying to use this for is to solve a different problem, which might have a more direct solution. I have an instance 'Eq (E RValue a)' and I want the type checker to pick that one when it runs into the constraint 'Eq (E v a)', because there's never going to be any other instance of 'Eq (E ...)'.
Of course, the type checker needs to be convinced of this. So I tried 'IsRValue v => Eq (E v a)', where IsRValue has a fundep that forces it to have (at most) one instance.
But then I ran into the bug I reported.
</p>
<p>
I think using this idiom is a reasonable way to tell the type checker that there will be at most one instance of a particular class.
</p>
<p>
The code:
</p>
<pre class="wiki">{-# OPTIONS_GHC -fglasgow-exts #-}
module E where
data E v a = E a
data RValue
{-
-- This fails with the message below.
instance (Eq a) => Eq (E RValue a) where
E x == E y = x == y
-- No instance for (Eq (E v Int))
-- arising from a use of `==' at E.hs:13:6-11
-}
-- This succeeds, but doesn't force v to be RValue
instance (Eq a) => Eq (E v a) where
E x == E y = x == y
{-
-- This fails with the message below.
instance (IsRValue v, Eq a) => Eq (E v a) where
E x == E y = x == y
class IsRValue a | -> a
instance IsRValue RValue
-- Ambiguous type variable `v' in the constraint:
-- `IsRValue v' arising from a use of `==' at E.hs:30:6-11
-}
a :: E v Int
a = undefined
foo = a == a
</pre>
TicketchakWed, 29 Aug 2007 13:28:12 GMT
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:4
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:4
<p>
This works with the latest head:
</p>
<pre class="wiki">{-# OPTIONS_GHC -fglasgow-exts #-}
module E where
data E v a = E a
data RValue
instance (v ~ RValue, Eq a) => Eq (E v a) where
E x == E y = x == y
a :: E v Int
a = undefined
foo = a == a
</pre><p>
So, I agree with SimonPJ, death to functional dependencies. This solution was btw SimonPJ's idea (he just couldn't test it as his latest build wasn't complete yet.)
</p>
<p>
<tt>t1 ~ t2</tt> is an equality constraint and part of the type families patch that landed in the head yesterday.
</p>
TicketguestWed, 29 Aug 2007 22:54:03 GMT
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:5
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:5
<p>
Using v ~ RValue works like a charm!
</p>
TicketsimonmarTue, 13 Nov 2007 11:08:51 GMTos, architecture changed
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:6
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:6
<ul>
<li><strong>os</strong>
changed from <em>MacOS X</em> to <em>Multiple</em>
</li>
<li><strong>architecture</strong>
changed from <em>x86</em> to <em>Multiple</em>
</li>
</ul>
TicketsimonpjTue, 13 Nov 2007 17:06:56 GMTstatus changed; resolution set
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:7
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:7
<ul>
<li><strong>status</strong>
changed from <em>new</em> to <em>closed</em>
</li>
<li><strong>resolution</strong>
set to <em>wontfix</em>
</li>
</ul>
<p>
I think we won't fix this; use type functions and equalities instead.
</p>
<p>
Simon
</p>
TicketsimonpjWed, 14 Nov 2007 08:16:11 GMTstatus, summary, milestone changed; resolution deleted
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:8
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:8
<ul>
<li><strong>status</strong>
changed from <em>closed</em> to <em>reopened</em>
</li>
<li><strong>summary</strong>
changed from <em>Type checker does not use fundep to avoid ambiguity</em> to <em>Type checker does not use functional dependency to avoid ambiguity</em>
</li>
<li><strong>resolution</strong>
<em>wontfix</em> deleted
</li>
<li><strong>milestone</strong>
changed from <em>6.8 branch</em> to <em>_|_</em>
</li>
</ul>
<p>
Re-opening because I recall that for these fundep issues we're giving them milestone "_|_".
</p>
TicketsimonmarTue, 30 Sep 2008 15:45:11 GMTarchitecture changed
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:9
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:9
<ul>
<li><strong>architecture</strong>
changed from <em>Multiple</em> to <em>Unknown/Multiple</em>
</li>
</ul>
TicketsimonmarTue, 30 Sep 2008 15:54:49 GMTos changed
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:10
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:10
<ul>
<li><strong>os</strong>
changed from <em>Multiple</em> to <em>Unknown/Multiple</em>
</li>
</ul>
TicketmorabbinSat, 26 Jan 2013 22:11:43 GMTfailure set
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:11
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:11
<ul>
<li><strong>failure</strong>
set to <em>None/Unknown</em>
</li>
</ul>
<p>
Bump; chak saya this was fixed in HEAD, and then SPJ closes as wontfix? Was the fix backed out?
</p>
TicketiglooSun, 27 Jan 2013 14:46:24 GMT
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:12
http://ghc.haskell.org/trac/ghc/ticket/1614#comment:12
<p>
If I understand correctly, it was chak's code that worked, not the code in the original description.
</p>
Ticket