Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you scale a vector using the Haskell library, Linear?

This is a simple question about style. I've been using:

import Linear
point  = V3 1 2 3
scaled = fmap (* 2) point

Or...

scaled = (* 2) <$> point

Is this the intended way, or is there a proper multiplication by scalar operator?

like image 263
MaiaVictor Avatar asked Jan 12 '15 16:01

MaiaVictor


1 Answers

The linear library exports an instance of Num a => Num (V3 a), so you can actually just do

> point * 2
V3 2 4 6

If you use GHCi, you can see what it means for 2 :: V3 Int:

> 2 :: V3 Int
V3 2 2 2

So the implementation of fromInteger for V3 would look like

fromInteger n = V3 n' n' n' where n' = fromInteger n

This means you can do things like

> point + 2
V3 3 4 5
> point - 2
V3 (-1) 0 1
> abs point
V3 1 2 3
> signum point
V3 1 1 1
> negate point
V3 (-1) (-2) (-3)

V3 also implements Fractional, so you should be able to use / and co. when your point contains Fractional values. However, the use of fmap is more general, you can convert your V3 Int into V3 String, for example:

> fmap show point
V3 "1" "2" "3"

The fmap function will let you apply a function of type a -> b to a V3 a to get a V3 b without any restrictions on the output type (necessarily so). Using fmap is not wrong, it's just not as readable as using the normal arithmetic operators. Most Haskellers wouldn't have any problems reading it, though, fmap is a very general tool that shows up for just about every type out there.

like image 92
bheklilr Avatar answered Oct 16 '22 11:10

bheklilr