{- |
module: Arithmetic.Ring
description: An abstract ring type
license: MIT
maintainer: Joe Leslie-Hurd
stability: provisional
portability: portable
-}
module Arithmetic.Ring
where
import OpenTheory.Primitive.Natural
import qualified Data.Maybe as Maybe
import Arithmetic.Utility
data Ring a = Ring
{fromNatural :: Natural -> a,
add :: a -> a -> a,
negate :: a -> a,
multiply :: a -> a -> a,
divide :: a -> a -> Maybe a}
zero :: Ring a -> a
zero r = fromNatural r 0
one :: Ring a -> a
one r = fromNatural r 1
two :: Ring a -> a
two r = fromNatural r 2
double :: Ring a -> a -> a
double r x = add r x x
subtract :: Ring a -> a -> a -> a
subtract r x y = add r x (Arithmetic.Ring.negate r y)
square :: Ring a -> a -> a
square r x = multiply r x x
exp :: Ring a -> a -> Natural -> a
exp r = multiplyExponential (multiply r) (one r)
exp2 :: Ring a -> a -> Natural -> a
exp2 r x k = functionPower (square r) k x
divides :: Ring a -> a -> a -> Bool
divides r x y = Maybe.isJust (divide r x y)
invert :: Ring a -> a -> Maybe a
invert r x = divide r (one r) x