<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Hi,</p>
<p>I am trying to understand how GHC treats the following
declaration.<br>
</p>
<pre>f c i = if i == 10 then c else g c 'b'
g 'a' w = f 'b' 10
g z w = z
l = (f 'a' (1::Int), f 'a' (1.0::Double))
</pre>
<p>It seems to me like, after defaulting, f should have the
following type:<br>
</p>
<pre> Char -> Int -> Char
</pre>
<p>However, looking at -ddump-tc, GHC is deriving the polymorphic
type <br>
</p>
<pre> forall a. (Eq a, Num a) => Char -> a -> Char</pre>
<p>That's much nicer, because its more flexible. But I'm confused,
because it looks like GHC is defaulting 'g', but not 'f', even
though they are in the same recursive group. This seems to
contradict "Typing Haskell in Haskell", which is what I am looking
at right now. If that is correct, can anybody point me to a paper
or documentation about how this works?<br>
</p>
<p>More detail:<br>
</p>
<p>1. If I understand correctly, the definitions of `f` and `g` are
mutually recursive, and should be typed together, and the
declaration group is not restricted.<br>
</p>
<p>2. It seems like, before generalization, we have</p>
<pre> f :: Char -> a -> Char
g :: Char -> Char -> Char
Predicates include (Eq a, Num a)
</pre>
<p>3. Looking at the paper "Typing Haskell in Haskell" (THIH), it
looks like the predicates (Num a, Eq a) should cause an ambiguity
in the definition of g:<br>
</p>
<p>* a is present in the definition of f, but not the definition of
g<br>
</p>
<p>* so the type (Eq a, Num a) => Char -> Char -> Char is
ambiguous.</p>
<p>* more generally, it seems like THIH treats any predicates with a
type variable that is part of some, but not all, types in the
declaration group to be ambiguous. Does this sound right?<br>
</p>
<p>4. Then, again following THIH, this ambiguous predicate should be
defaulted to Int.<br>
</p>
<p>I THINK this should lead to</p>
<pre> f :: Char -> Int -> Char
g :: Char -> Char -> Char
</pre>
<p>5. However, I'm still not sure I'm understanding this right,
because a few things still don't make sense:<br>
</p>
<p>* First, THIH seems to eliminate the defaulted predicates without
substituting a -> Int. But the type for f DOES mention `a`, so
how can we avoid substituting?<br>
</p>
<p>* Second, GHC accepts the code with no warnings or errors. There
is some kind of defaulting going on, because GHC rejects the code
if I add "default ()". Is there some way for GHC to default only
g, but not f? <br>
</p>
<p>I wonder if this involves a difference between Haskell '98 and
Haskell 2010?</p>
<p>I also wonder how much I should rely on THIH? Maybe the language
has moved on since then?</p>
<p>-BenRI<br>
</p>
</body>
</html>