开发者

Haskell - add typeclass?

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜