[Haskell] Instance declaration of classes with method type constraints

Wolfgang Jeltsch wolfgang at jeltsch.net
Thu Jun 30 08:30:50 EDT 2005


Am Donnerstag, 30. Juni 2005 14:07 schrieb Johan Holmquist:
> [...]

> Anyone:
>
> However, I haven't been able to make PRect an instance of this class (with
> extensions).

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 
other.

> 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.

> regards
> /johan

Best wishes,
Wolfgang


More information about the Haskell mailing list