GHC: Ticket #7594: GHCi becomes confused about IO type
http://ghc.haskell.org/trac/ghc/ticket/7594
<pre class="wiki">{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE Rank2Types #-}
import GHC.Prim (Constraint)
class (c1 t, c2 t) => (:&:) (c1 :: * -> Constraint) (c2 :: * -> Constraint) (t :: *)
instance (c1 t, c2 t) => (:&:) c1 c2 t
data ColD c where
ColD :: (c a) => a -> ColD c
app :: (forall a. (c a) => a -> b) -> ColD c -> b
app f (ColD x) = f x
q :: ColD (Show :&: Real)
q = ColD (1.2 :: Double)
</pre><p>
In the interactive mode it's possible to confuse GHCi about IO type. It tries to show expression instread of executing it.
</p>
<pre class="wiki">*Main> app print q
<interactive>:3:1:
No instance for (Show (IO ())) arising from a use of `print'
Possible fix: add an instance declaration for (Show (IO ()))
In a stmt of an interactive GHCi command: print it
</pre>en-usGHChttp://ghc.haskell.org/trac/ghc/chrome/site/ghc_logo.png
http://ghc.haskell.org/trac/ghc/ticket/7594
Trac 1.0.9simonpjWed, 16 Jan 2013 13:58:40 GMTstatus changed; difficulty, resolution set
http://ghc.haskell.org/trac/ghc/ticket/7594#comment:1
http://ghc.haskell.org/trac/ghc/ticket/7594#comment:1
<ul>
<li><strong>status</strong>
changed from <em>new</em> to <em>closed</em>
</li>
<li><strong>difficulty</strong>
set to <em>Unknown</em>
</li>
<li><strong>resolution</strong>
set to <em>worksforme</em>
</li>
</ul>
<p>
Hmm. Absolutely right, and this happens for 7.6.2 too. However with HEAD we get:
</p>
<pre class="wiki"><interactive>:2:5:
Couldn't match type `b' with `IO ()'
`b' is untouchable
inside the constraints ((:&:) Show Real a)
bound by a type expected by the context:
(:&:) Show Real a => a -> b
at <interactive>:2:1-11
`b' is a rigid type variable bound by
the inferred type of it :: b at <interactive>:2:1
</pre><p>
This is actually right, although the error message is not so easy. We know that
</p>
<pre class="wiki">print :: Show a => a -> IO ()
</pre><p>
We also know (by way of the argument <tt>q</tt>, that <tt>c = (Show :&: Real) a</tt>. So, to check that <tt>print</tt> is a valid argument to <tt>app</tt>, we must check that
</p>
<pre class="wiki">From (Show :&: Real) a
prove that (Show a, beta ~ IO ())
</pre><p>
where <tt>beta</tt> is a unification variable (as-yet-unknown type) obtained by instantiating <tt>app</tt>.
</p>
<p>
Well, you say, we can choose <tt>beta</tt> to be <tt>IO ()</tt> and we are done. But not so: in general the "<tt>From</tt>" constraints might include GADT-style equalites, and GHC is careful NOT to unify under equality constraints. (See the <a class="ext-link" href="http://haskell.org/haskellwiki/Simonpj/Talk:OutsideIn"><span class="icon"></span>Modular type inference with local assumptions</a> paper.) That's why <tt>beta</tt> is "untouchable".
</p>
<p>
Easily fixed by saying <tt>app print q :: IO ()</tt>, and that works fine.
</p>
<p>
I am strongly dis-inclined to attempt to find out what's happening in 7.6! So I propose just to close this. I might add a regression test though.
</p>
<p>
Simon
</p>
TicketsimonpjFri, 18 Jan 2013 17:30:48 GMTtestcase set
http://ghc.haskell.org/trac/ghc/ticket/7594#comment:2
http://ghc.haskell.org/trac/ghc/ticket/7594#comment:2
<ul>
<li><strong>testcase</strong>
set to <em>polykinds/T7594</em>
</li>
</ul>
Ticket