利用FlexibleInstances快速推理Num/Fractional

直接上代码:

{-# 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.VectorApplicave Instances的行为不太符合向量化的一般意义,所以最好用另外一个类似Applicative的typeclass来替换。

你可能感兴趣的:(利用FlexibleInstances快速推理Num/Fractional)