module Music.Theory.Z where
import Data.List
lift_unary_Z :: Integral a => a -> (t -> a) -> t -> a
lift_unary_Z z f n = mod (f n) z
lift_binary_Z :: Integral a => a -> (s -> t -> a) -> s -> t -> a
lift_binary_Z z f n1 n2 = mod (n1 `f` n2) z
z_add :: Integral a => a -> a -> a -> a
z_add z = lift_binary_Z z (+)
z_sub :: Integral a => a -> a -> a -> a
z_sub z = lift_binary_Z z ()
z_mul :: Integral a => a -> a -> a -> a
z_mul z = lift_binary_Z z (*)
z_negate :: Integral a => a -> a -> a
z_negate z = lift_unary_Z z negate
z_fromInteger :: Integral a => a -> Integer -> a
z_fromInteger z i = fromInteger i `mod` z
z_signum :: t -> t1 -> t2
z_signum _ _ = error "Z numbers are not signed"
z_abs :: t -> t1 -> t2
z_abs _ _ = error "Z numbers are not signed"
to_Z :: Integral i => i -> i -> i
to_Z z = z_fromInteger z . fromIntegral
from_Z :: (Integral i,Num n) => i -> n
from_Z = fromIntegral
z_complement :: (Enum a, Eq a, Num a) => a -> [a] -> [a]
z_complement z = (\\) [0 .. z 1]
z_quot :: Integral i => i -> i -> i -> i
z_quot z p = to_Z z . quot p
z_rem :: Integral c => c -> c -> c -> c
z_rem z p = to_Z z . rem p
z_div :: Integral c => c -> c -> c -> c
z_div z p = to_Z z . div p
z_mod :: Integral c => c -> c -> c -> c
z_mod z p = to_Z z . mod p
z_quotRem :: Integral t => t -> t -> t -> (t, t)
z_quotRem z p q = (z_quot z p q,z_quot z p q)
z_divMod :: Integral t => t -> t -> t -> (t, t)
z_divMod z p q = (z_div z p q,z_mod z p q)
z_toInteger :: Integral i => i -> i -> i
z_toInteger z = to_Z z