Reputation: 26354
data Vector a = Vector a a a deriving (Eq, Show)
instance Functor Vector where
fmap f (Vector x y z) = Vector (f x) (f y) (f z)
So far so good.
instance Num ((Num a) => Vector a) where
negate = fmap negate
Doesn't work. I tried many different variations on that first line but GHC keeps complaining. I want to make a Vector
containing numbers an instance of Num
; surely this should be possible? Otherwise I would have to make an instance for Int
, Integer
, Float
, Double
, etc. all with the same definition.
Upvotes: 1
Views: 2576
Reputation: 119847
It is probably a bad idea to make Vector
an instance of Num
. Here's the declaration of Num
:
class Num a where
(+) :: a -> a -> a
(*) :: a -> a -> a
(-) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
+
and -
and negate
are no problem. One can define *
as cross product, but only for 3-vectors, and this is really stretching it. abs
, signum
and fromInteger
have no meaningful definitions.
In short, it is possible to shoehorn Vector
into Num
, but the result is not nice.
You may want to explore alternative type class hierarchies which replace the standard Prelude ones, e.g. the Numeric prelude.
Upvotes: 2
Reputation: 25644
instance Num a => Num (Vector a) where
negate = fmap negate
Consider writing other methods too.
(You can write deriving (Eq, Show, Functor)
if you turn on -XDeriveFunctor
.)
Upvotes: 8