haskellhigher-kinded-typestype-variables

Higher kinded types as type variables in Haskell


I have a class:

import Linear

class Coordinate c where
    rotate :: Num a => Quaternion a -> c a -> c a
    translate :: Num a => V3 a -> c a -> c a

, for which I have defined the instances

instance Coordinate V3 where
    rotate _ = id
    translate p = (p+)

instance Coordinate Quaternion where
    rotate o = (o*)
    translate _ = id

Now I want to define an instance for a pair of members of the class.

instance (Coordinate a, Coordinate b) => Coordinate (a, b) where
    rotate o (a, b) = (rotate o a, rotate o b)
    translate p (a, b) = (translate p a, translate p b)

The problem is that this does not work, since the compiler expects an argument for a and b. However adding a type-constraint like

instance (Coordinate a, Coordinate b, Num c) => Coordinate (a c, b c) where
    move p (a, b) = (move p a, move p b)
    translate p (a, b) = (translate p a, translate p b)

It does not work either, since this results in an expression with the kind * rather than * -> *. I can see how both of the above are incorrect, but I am unsure of how to solve this. I suppose there should be some form of constraint that keeps the Num types for both aand b the same, but I don't know what that would look like syntactically.


Solution

  • You cannot make an instance of this Coordinate class for the built-in pair type. You need to change one of them.