Different Behavior between Numeric Literals and Constrained Function
Parameters in Haskell
I've been trying to figure out the more finnicky bits of Haskell's type
system by writing a Vector library. Ideally, I'd like an overloaded vector
multiplication operation that works a bit like C++, i.e, you can multiply
a vector of any size by a scalar, in either order. I've tried to combine
the multiple parameter type classes and type families extension to do
this:
data Vec2 a = Vec2 (a,a) deriving (Show, Eq, Read)
class Vector a where
(<+>) :: a -> a -> a
class VectorMul a b where
type Result a b
(<*>) :: a -> b -> Result a b
instance (Num a) => Vector (Vec2 a) where
Vec2 (x1,y1) <+> Vec2 (x2,y2) = Vec2 (x1+x2, y1+y2)
instance (Num a) => VectorMul (Vec2 a) a where
type Result (Vec2 a) a = (Vec2 a)
Vec2 (x,y) <*> a = Vec2 (x*a, y*a)
works :: (Num a) => Vec2 a -> a -> Vec2 a
works a b = a <*> b
This code seems to work, at least when used as in the function "works".
But when I try to type a simple expression like "Vec2 (3,4) <*> 5" into
GHCi, it reports the (Num xx) type variables to be ambiguous. This is
strange to me... what am I missing in this case? Haskell should be able to
choose the same arbitrary type for the literals, to make the type
expression work (as it does in the works function).
No comments:
Post a Comment