How do I write the type of 'inverse'?
Sat, 17 Nov 2001 06:29:54 +1300 (NZDT)
I have a class whose instances can extract a field of type a.
Is there a way of referring to that type 'a' in the signatures
of functions that use the class? Sigh! That wasn't very clear.
I'll try explaining via example:
I am trying to define a `Pairable' class, which is an abstraction
of all kinds of pairs: (a,b), Pair a b, etc.
> class Ord p => Pairable p where
> is_pair :: p -> Bool
> pair_fst :: Ord a => p -> a -- Precondition: is_pair
> pair_snd :: Ord b => p -> b -- Precondition: is_pair
> make_pair :: (Ord a, Ord b) => a -> b -> p
> instance (Ord a, Ord b) => Pairable (a,b) where
> is_pair (a,b) = True
> pair_fst (a,b) = a
> pair_snd (a,b) = b
> make_pair a b = (a,b)
I then want to define a `Relation' to be a set of Pairable values.
> newtype Pairable p => Reln p = Reln [p]
This works okay for many of my relation operations.
But I run into an interesting problem with `inverse'
(which swaps the components of each pair).
inverse :: (Pairable p, Pairable p2) => Reln p -> Reln p2
inverse rs = Reln[make_pair (pair_snd p) (pair_fst p) | p <- reln2list rs]
Hugs gives the error:
ERROR /home/utting/jaza/tmp.hs:19 - Cannot justify constraints in explicitly
*** Expression : inverse
*** Type : (Pairable a, Pairable b) => Reln a -> Reln b
*** Given context : (Pairable a, Pairable b)
*** Constraints : (Ord c, Ord d)
which I can understand.
BUT, I cannot see any way of naming the `component types', c and d,
in the signature of inverse!
It seems like I want to pass the component types into the
class definition somehow: class Pairable (p a b)
How does one normally get around this kind of problem?
Laboratoire d'Informatique de l'Université de Franch-Comté
16, route de Gray - 25000 Besançon, cedex, FRANCE
Tel: (33) 3 81 66 20 69
Fax: (33) 3 81 66 64 50