oleg | 11 May 07:03 2013

Typeclass with an `or' restriction.


Mateusz Kowalczyk wrote:
> Is there a way however to do something along the lines of:
> > class Eq a => Foo a where bar :: a -> a -> Bool bar = (==)
> >
> > class Num a => Foo a where bar :: a -> a -> Bool bar _ _ = False
> This would allow us to make an instance of Num be an instance of Foo
> or an instance of Eq to be an instance of Foo.

GADTs are a particular good way to constraint disjunction, if you can live
with the closed universe. (In the following example I took a liberty
to replace Int with Ord, to make the example crispier.)

> {-# LANGUAGE GADTs #-}
>
> data OrdEq a where
>     Ord :: Ord a => OrdEq a             -- representation of Ord dict
>     Eq  :: Eq a  => OrdEq a             -- representation of Eq dict
>
> bar :: OrdEq a -> a -> a -> Bool
> bar Ord x y = x > y
> bar Eq  x y = x == y

The function bar has almost the desired signature, only (OrdEq a ->)
has the ordinary arrow rather than the double arrow. We can fix that:

> class Dict a where
>     repr :: OrdEq a
>
> -- We state that for Int, we prefer Ord
(Continue reading)


Gmane