美文网首页Haskell
利用FlexibleInstances快速推理Num/Fract

利用FlexibleInstances快速推理Num/Fract

作者: DarkBubble | 来源:发表于2018-09-20 22:08 被阅读0次

    直接上代码:

    {-# 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/Fract

        本文链接:https://www.haomeiwen.com/subject/qulonftx.html