Type classes and code generation
Keith Wansbrough
Keith.Wansbrough@cl.cam.ac.uk
Tue, 17 Jun 2003 16:05:18 +0100
> (Moved to the Cafe)
>
> > Yes, exactly. Every class is translated to a data type declaration,
> > and every instance is translated to an element of that data type - a
> > dictionary. (Note that you can't actually write those declarations in
> > Haskell 98 in general, because they can have polymorphic fields; but
> > this is a simple extension to the language).
>
> Keith, could you elaborate on this parenthetical? Under what
> circumstances can you not create the dictionary datatype for a class in
> Haskell 98 (where the class itself is H98 :P)?
Sure:
> class C a where
> pair :: b -> (b,a)
>
> instance C () where
> pair x = (x,())
>
> instance C Int where
> pair x = (x,42)
>
> main = do print (pair "hello" :: (String,()))
> print (pair "world" :: (String,Int))
is perfectly fine Haskell 98.
But
> data C a = C { pair :: b -> (b,a) }
>
> dCUnit = C { pair = \ x -> (x,()) }
>
> dCInt = C { pair = \ x -> (x,42::Int) }
>
> main = do print (pair dCUnit "hello" :: (String,()))
> print (pair dCInt "world" :: (String,Int))
doesn't work:
classprob2.hs:1: Type variable not in scope: `b'
classprob2.hs:1: Type variable not in scope: `b'
You need to change the first line to this:
> data C a = C { pair :: forall b. b -> (b,a) }
and then it works fine (with -fglasgow-exts). But you've now stepped
outside the bounds of Haskell 98.
This is a contrived example, but Functor and Monad from the standard
Prelude both have this property - they have universally-quantified
variables in the types of some of their methods; not all their
variables are constrained by the class constraint.
HTH.
--KW 8-)