{- | Module : Data.Matrix.AsXYZ.Common Copyright : (c) Jun Narumi 2020 License : BSD3 Maintainer : narumij@gmail.com Stability : experimental Portability : ? -} module Data.Matrix.AsXYZ.Common ( Sign(..), Var(..), Val(..), rowVars, ) where import Data.Ratio import Numeric data Sign a = P a | N a | Zero deriving (Show,Eq) data Var a = X a | Y a | Z a | W a deriving (Show,Eq) -- 数値の型情報 data Val a -- 整数 = I a -- 浮動小数 | F a -- 分数 | R a deriving Show instance Functor Var where fmap f (X a) = X (f a) fmap f (Y a) = Y (f a) fmap f (Z a) = Z (f a) fmap f (W a) = W (f a) instance Functor Val where fmap f (I a) = I (f a) fmap f (F a) = F (f a) fmap f (R a) = R (f a) rowVars :: Integral a => [Ratio a] -> [Sign (Var (Ratio a))] rowVars = reduceVars . sortVars . toVars toVars :: Integral a => [Ratio a] -> [Sign (Var (Ratio a))] toVars = zipWith (\a b -> hoge a b) [X,Y,Z,W] where hoge f r | r < 0 = N $ f (r * (-1)) | otherwise = P $ f r sortVars :: Eq a => [Sign (Var a)] -> [Sign (Var a)] sortVars parts | null hh = parts | otherwise = h: filter (/= h) parts where hh = filter isPrimary parts h = head hh -- 正の係数がついた変数である isPrimary :: Sign (Var a) -> Bool isPrimary Zero = False isPrimary (N _) = False isPrimary (P (W _)) = False isPrimary _ = True reduceVars :: (Eq a, Num a) => [Sign (Var a)] -> [Sign (Var a)] reduceVars rr = if null a then [Zero] else a where a = filter (not . isZero) rr isZero :: (Eq a, Num a) => Sign (Var a) -> Bool isZero (N v) = isZero' v isZero (P v) = isZero' v isZero Zero = True isZero' :: (Eq a, Num a) => Var a -> Bool isZero' (X n) = n == 0 isZero' (Y n) = n == 0 isZero' (Z n) = n == 0 isZero' (W n) = n == 0