I’m trying to implement the Cantor Pairing Function, as an instance of a
generic Pair typeclass, as so:
module Pair (Pair, CantorPair) where
-- Pair interface
class Pair p where
pi :: a -> a -> p a
k :: p a -> a
l :: p a -> a
-- Wrapper for typing
newtype CantorPair a = P { unP :: a }
-- Assume two functions with signatures:
cantorPair :: Integral a => a -> a -> CantorPair a
cantorUnpair :: Integral a => CantorPair a -> (a, a)
-- I need to somehow add an Integral a constraint to this instance,
-- but I can't work out how to do it.
instance Pair CantorPair where
pi = cantorPair
k = fst . cantorUnpair
l = snd . cantorUnpair
How can I add the appropriate Integral constraint to the instance?
I have a vague feeling I might need to modify the Pair interface itself,
but not sure how to go about this.
Do you want all pairs to always contain integral elements? In this case, you could add the constraint to the signatures of the methods:
This will make you pair class less general but will ensure that your
CantorPairtype could be a part of it.If you want to keep your
Pairclass somewhat general, you could use a multi parameter type class. (This will require two extensions:MultiParamTypeClassesandFlexibleInstances.)I don’t know if this is necessarily the best option from a design standpoint, but it’s a good way to learn about how multiparamter type classes work. (Which, admittedly, is fairly simple.)