Haskell Vector Typeclass: Function [a] & # 8594; [a] & # 8594; a

Ok, I'm trying to wrap my head in cool classes, and so I'm trying to define typeclass for geometric vector operations. I managed to get it to work for component +,-,*,/; but I am struggling with a point product.

 class GeomVector a where (>+) :: a -> a -> a (>-) :: a -> a -> a (>*) :: a -> a -> a (>/) :: a -> a -> a (>.) :: a -> a -> Double data Vector a = Vec [a] deriving Show instance (Fractional a) => GeomVector (Vector a) where (>+) (Vec u) (Vec v) = Vec $ zipWith (+) uv (>-) (Vec u) (Vec v) = Vec $ zipWith (-) uv (>*) (Vec u) (Vec v) = Vec $ zipWith (*) uv (>/) (Vec u) (Vec v) = Vec $ zipWith (/) uv (>.) (Vec u) (Vec v) = sum $ u >* v 

Obviously, my instance definition for (>.) Will not work, because the result is of type Fractional a , not Double .

But I do not know how to get this behavior from the declaration in the class.

I would like to:

 class GeomVector [a] where (>.) :: [a] -> [a] -> a 

But this is not true because [a] is a type, not a type variable.

I would like to explain this a little better, but I honestly do not understand enough about this. Hopefully the code will make it more obvious what I'm struggling with.

+6
source share
1 answer

Here is one option that might work:

 class GeomVector v where (>+) :: Num a=> va -> va -> va (>-) :: Num a=> va -> va -> va (>*) :: Num a=> va -> va -> va (>/) :: Fractional a=> va -> va -> va (>.) :: Num a=> va -> va -> a data Vector a = Vec { vecList :: [a] } deriving Show instance GeomVector Vector where (>+) (Vec u) (Vec v) = Vec $ zipWith (+) uv (>-) (Vec u) (Vec v) = Vec $ zipWith (-) uv (>*) (Vec u) (Vec v) = Vec $ zipWith (*) uv (>/) (Vec u) (Vec v) = Vec $ zipWith (/) uv (>.) uv = sum $ vecList (u >* v) 

Thus, all your instances of GeomVector will look like * -> * , like the Monad class. And the types of methods are not necessarily limited to Fractional types just because you are sharing somewhere there.

You might also consider making your class as small as possible (make >. polymorphic function outside the class), and if what you really want is a type class. But it all depends on what you are developing, and I do not want to assume that I know better than you about this!

+5
source

All Articles