mk12
mk12

Reputation: 26354

Haskell: Num instance of non-concrete type

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

Answers (2)

n. m. could be an AI
n. m. could be an AI

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

sdcvvc
sdcvvc

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

Related Questions