You are in luck!
Such an instance is very simple with Applicative. If the type you want a Num instance for is a member of the Applicative type class you can define it like this:
instance (Num a) => Num (Vector2 a) where
a + b = pure (+) <*> a <*> b
a - b = pure (-) <*> a <*> b
a * b = pure (*) <*> a <*> b
negate a = pure negate <*> a
abs a = pure abs <*> a
signum = fmap signum
fromInteger = pure . fromInteger
If you want to define a Num instance for _all_ applicatives, you can do this (you'll need a couple extensions):
instance (Num a, Applicative f, Eq (f a), Show (f a)) => Num (f a) where
a + b = pure (+) <*> a <*> b
a - b = pure (-) <*> a <*> b
a * b = pure (*) <*> a <*> b
negate a = pure negate <*> a
abs a = pure abs <*> a
signum = fmap signum
fromInteger = pure . fromInteger
I am currently working on a vector and matrix library for haskell that uses instances of this form, which you can find here: http://github.com/jvranish/VectorMatix. The matrix half is very unfinished, but the vector half is pretty much done.
Applicative is a pretty fantastic typeclass, it's definitly worth the time to figure out how it works.
However, this technique won't work with tuples as they don't behave as Functors in the way you would like. (too many type parameters, tuples don't force all elements to be the same type so maps don't work, etc...)
Hope that helps :)
- Job
Hi!
I often stumble upon 2- (or 3-) dimensional numerical data types like
(Double, Double)
or similar self defined ones. I like the idea of creating instances for Num for
these types. The meaning of (+), (-) and negate is clear and very intuitive, i
think. I don't feel sure about (*), abs, signum and fromInteger. I used to
implement
fromInteger n = (r, r) where r = fromInteger n
, but thinking about it,
fromInteger n = (fromInteger n, 0)
seems very reasonable, too.
Any thoughts on that? How would you do it?
btw: These are two examples i looked at in hackage:
Data.Complex.Complex (which is special, cause it is mathematically defined,
what (*), abs, signum and fromInteger should do (i think))
and
Physics.Hipmunk.Common.Vector
(http://hackage.haskell.org/packages/archive/Hipmunk/5.0.0/doc/html/Physics-
Hipmunk-Common.html#9)
Sönke
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe