An interesting example.  The message that GHC produces if you leave
the type signature in is:

Cls.hs:13:
    Ambiguous type variable(s) `a' in the constraint `X a'
    arising from use of `h' at Cls.hs:13
    In the first argument of `g', namely `(h b)'
    In the first argument of `f', namely `(g (h b))'

This is actually quite right.  If h is *polymorphic* in its own right hand
side
(as it becomes if you give a type signature) then the call (h b)
returns a result of type (a c), and requires (X a).  But alas, g then
cosumes
the value of type (a c) and returns one of type c -- so there is no way to
figure out what type 'a' is.

When h is monomorphic in its own right hand side, things are fine.

I have to admit that this is the first time I've seen an example where
adding a type signature makes a program *un* typable!

Simon


| -----Original Message-----
| From: Levent Erkok [mailto:[EMAIL PROTECTED]]
| Sent: 02 June 2000 02:09
| To: [EMAIL PROTECTED]
| Subject: types: checking vs. inferring
| 
| 
| Hi,
| 
| I've come accross an interesting bit of code:
| ==============================================================
| ==============
| class X a where
|   u :: a b -> a b
|  
| f :: X a => b -> a b
| f = f
|  
| g :: X a => a b -> b
| g = g
|  
| -- h :: X a => b -> a c  
| h b = f (g (h b))            
| ==============================================================
| ================
| 
| Hugs admits the script as it is. When asked for the type of 
| h, it says:
| 
| Main> :t h
| h :: X a => b -> a c    
| 
| But, when you add the type of h to the script (i.e. uncomment the 
| type declaration for h), it says:
| 
| Type checking
| ERROR "a.hs" (line 11): Cannot justify constraints in 
| explicitly typed binding
| *** Expression    : h
| *** Type          : X a => b -> a c
| *** Given context : X a
| *** Constraints   : X d      
| 
| Looks like polymorphic recursion in the presence of type 
| classes confuses the
| type checker (?)
| 
| This is interesting since if I tell tell the system what it 
| can deduce, it gets
| confused. GHC behaves similarly, so I suspect this is a 
| Haskell problem, rather
| than a particular implementation. Any comments?
| 
| -Levent.
| 

Reply via email to