[Haskell] Instance declaration of classes with method type constraints
wolfgang at jeltsch.net
Thu Jun 30 08:30:50 EDT 2005
Am Donnerstag, 30. Juni 2005 14:07 schrieb Johan Holmquist:
> However, I haven't been able to make PRect an instance of this class (with
If I understand your problem correctly, you may use the new Rect class (the
one which is declared as class Num b => Rect a b | a -> b where ...) and add
an instance Num a => Rect (PRect a) a where ...
> I might not have grasped this yet, but I came to think; if the old class
> declaration would say that "width" and "height" returns something with
> unfixed type in the "Num" class, then wouldn't it be possible to make PRect
> an instance of that class (since PRect has a type parameter)?
> Something like this:
> class Rect a where
> width :: (Num b) => a -> b
> height :: (Num b) => a -> b
This means that for every type a which is an instance of Rect there is a width
and a height of an arbitrary Num type. a and b are independent of each
> data Num a => PRect a = PRect (a, a) (a, a) deriving (Eq, Show)
> instance Rect PRect a where ...
> This (as well as my other attemps) fail with a "Kind error: `PRect' is not
> applied to enough type arguments" - error. Is there a way to do it, or am I
> lost here?
PRect is of kind * -> *. A type has kind * if an expression can have this
type. Examples of kind * types are Int, [Int], PRect Int and PRect a. Kind
* -> * means that applying the type to a type of kind * yields a type of kind
*. PRect (without any arguments) is an example of a kind * -> * type as well
as . From the type declarations of width an height it is clear that a has
to have kind *. So you cannot use PRect for a. You could use PRect c for a
but that would mean that width and height would have type Num b =>
PRect c -> b each, i.e. that c and b would be independent.
Another solution would be the following:
class Rect r where
height :: Num b => r b -> b
width :: Num b => r b -> b
Because r is applied to b in the type of height and width, r is of kind
* -> *. Now you could write
instance Rect PRect where ...
But you wouldn't be able to do something like
instance Rect IRect where ...
anymore since IRect is clearly of kind *. With this solution, you would have
to have types r of kind * -> * and for every Num instance b, values of type
r b would have to have a height and a width.
More information about the Haskell