[Haskell-cafe] How do I simulate dependent types using phantom types?

Twan van Laarhoven twanvl at gmail.com
Sat Aug 18 15:37:58 EDT 2007


DavidA wrote:

> Hi,
> 
> I am trying to implement quadratic fields Q(sqrt d). These are numbers of the 
> form a + b sqrt d, where a and b are rationals, and d is an integer.
> 
> ...
>
> class IntegerType a where
>     value :: Integer
> 
> The problem is, this doesn't work. GHC complains:
>     The class method `value'
>     mentions none of the type variables of the class IntegerType a
>     When checking the class method: value :: Integer
>     In the class declaration for `IntegerType'
> 
> Is what I'm trying to do reasonable? If no, what should I be doing instead? If 
> yes, why doesn't GHC like it?

You are on the right track. The problem with the class method is that it 
doesn't use type 'a' anywhere, consider
 > f :: Integer
 > f = value
What class instance should be used here?

The solution is to use a dummy parameter:
 > class IntegerType a where
 >     value :: a -> Integer
And call it like:
 > f = value (undefined :: Two)

So for instance:
 > instance IntegerType d => Show (QF d) where
 >     show (QF a b) = show a ++ " + " ++ show b ++ " sqrt "
 >                   ++ show (value (undefined::d))

The problem is that this doesn't work, because d is not in scope, you 
need the scoped type variables extension:

 > valueOfQF :: forall a. IntegerType a => QF a -> Integer
 > valueOfQF qf = value (undefined :: a)

or maybe better, change the class:

 > class IntegerType a where
 >     value :: QF a -> Integer

Now you can simply use

 > instance IntegerType d => Show (QF d) where
 >     show qf@(QF a b) = show a ++ " + " ++ show b ++ " sqrt "
 >                     ++ show (value qf)

Twan


More information about the Haskell-Cafe mailing list