11 May 07:03 2013

## Typeclass with an `or' restriction.

<oleg <at> okmij.org>

2013-05-11 05:03:24 GMT

2013-05-11 05:03:24 GMT

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)