Consider the following example:
data Dot = Dot Double Double
data Vector = Vector Double Double
First, i would like to overload +
operator for Vector
addit开发者_运维技巧ion. If i wanted to overload equality(==
) operator, i would write it like:
instance Eq Vector where ...blahblahblah
But I can't find if there is Add
typeclass to make Vector
behave like a type with addition operation. I can't even find a complete list of Haskell typeclasses, i know only few from different tutorials. Does such a list exist?
Also, can I overload +
operator for adding Vector
to Dot
(it seems rather logical, doesn't it?).
An easy way to discover information about which typeclass (if any) a function belongs to is to use GHCi:
Prelude> :i (+)
class (Eq a, Show a) => Num a where
(+) :: a -> a -> a
...
-- Defined in GHC.Num
infixl 6 +
The operator + in Prelude is defined by the typeclass Num. However as the name suggests, this not only defines addition, but also a lots of other numeric operations (in particular the other arithmetic operators as well as the ability to use numeric literals), so this doesn't fit your use case.
There is no way to overload just + for your type, unless you want to hide Prelude's + operator (which would mean you have to create your own Addable instance for Integer, Double etc. if you still want to be able to use + on numbers).
You can write an instance Num Vector
to overload +
for vector addition (and the other operators that make sense).
instance Num Vector where
(Vector x1 y1) + (Vector x2 y2) = Vector (x1 + x2) (y1 + y2)
-- and so on
However, note that +
has the type Num a => a -> a -> a
, i.e. both operands and the result all have to be the same type. This means that you cannot have a Dot
plus a Vector
be a Dot
.
While you can hide Num
from the Prelude
and specify your own +
, this is likely to cause confusion and make it harder to use your code together with regular arithmetic.
I suggest you define your own operator for vector-point addition, for example
(Dot x y) `offsetBy` (Vector dx dy) = Dot (x + dx) (y + dy)
or some variant using symbols if you prefer something shorter.
I sometimes see people defining their own operators that kind of look like ones from the Prelude. Even ++
probably uses that symbol because they wanted something that conveyed the idea of "adding" two lists together, but it didn't make sense for lists to be an instance of Num
. So you could use <+>
or |+|
or something.
精彩评论