直接上代码:
{-# LANGUAGE FlexibleInstances #-}
module Vector where
import GHC.Base(liftA2)
data Vector2 a = Vector2 a a deriving(Eq, Show, Read)
data Vector3 a = Vector3 a a a deriving(Eq, Show, Read)
data Vector4 a = Vector4 a a a a deriving(Eq, Show, Read)
-- Instances of Functor
instance Functor Vector2 where
fmap f (Vector2 x y) = Vector2 (f x) (f y)
instance Functor Vector3 where
fmap f (Vector3 x y z) = Vector3 (f x) (f y) (f z)
instance Functor Vector4 where
fmap f (Vector4 x y z w) = Vector4 (f x) (f y) (f z) (f w)
-- Instances of Appilcative
instance Applicative Vector2 where
pure x = Vector2 x x
liftA2 f (Vector2 x1 y1) (Vector2 x2 y2) = Vector2 (f x1 x2) (f y1 y2)
instance Applicative Vector3 where
pure x = Vector3 x x x
liftA2 f (Vector3 x1 y1 z1) (Vector3 x2 y2 z2) = Vector3 (f x1 x2) (f y1 y2) (f z1 z2)
instance Applicative Vector4 where
pure x = Vector4 x x x x
liftA2 f (Vector4 x1 y1 z1 w1) (Vector4 x2 y2 z2 w2) = Vector4 (f x1 x2) (f y1 y2) (f z1 z2) (f w1 w2)
-- Instances of Num
instance (Applicative f, Num a) => Num (f a) where
(+) = liftA2 (+)
(-) = liftA2 (-)
(*) = liftA2 (*)
negate = fmap negate
abs = fmap abs
signum = fmap signum
fromInteger = pure . fromInteger
-- Instances of Fractional
instance (Applicative f, Fractional a) => Fractional (f a) where
(/) = liftA2 (/)
recip = fmap recip
fromRational = pure . fromRational
向量化问题以最精简的方式解决。不过由于[]
和Data.Vector
的Applicave Instances
的行为不太符合向量化的一般意义,所以最好用另外一个类似Applicative
的typeclass来替换。
网友评论