The type of (*) :: Num a => a -> a -> a
. But when you are actually trying to use *
, you are actually multiplying two unrelated types having Num
instances and the compiler is not able to infer that they are same.
To explain it more clearly look at the type of <*
and the universal quantification of b
(<*) :: (Num b) => a -> b -> a
What you are saying here is, give me any type having Num
instance and I will be able to multiply that with my vector, but what you want to say is something different.
You need to some how say that a
in the type Vec2 a
is same as b
in the type (<*) :: Num b => a -> b -> a
, only then you can multiply them together. Here is a solution using typefamilies to ensure this constraint.
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
data Vec2 a = Vec2 (a,a) deriving (Show, Eq, Read)
class (Num (VectorOf a)) => Vector a where
type VectorOf a :: *
(<*) :: a -> (VectorOf a) -> a
instance (Num a) => Vector (Vec2 a) where
type VectorOf (Vec2 a) = a
Vec2 (x,y) <* a = Vec2 (a*x, a*y)