module Numeric.NonNegative.Class (
C(..),
splitDefault,
(-|),
zero,
add,
sum,
maximum,
switchDifferenceNegative,
switchDifferenceOrdering,
) where
import Data.Monoid (Monoid, )
import qualified Data.Monoid as Monoid
import Prelude hiding (sum, maximum, )
class (Ord a, Monoid a) => C a where
split :: a -> a -> (a, (Bool, a))
{-# INLINE splitDefault #-}
splitDefault ::
(Ord b, Num b) =>
(a -> b) -> (b -> a) -> a -> a -> (a, (Bool, a))
splitDefault :: forall b a.
(Ord b, Num b) =>
(a -> b) -> (b -> a) -> a -> a -> (a, (Bool, a))
splitDefault a -> b
unpack b -> a
pack a
px a
py =
let x :: b
x = a -> b
unpack a
px
y :: b
y = a -> b
unpack a
py
in if b
xb -> b -> Bool
forall a. Ord a => a -> a -> Bool
<=b
y
then (b -> a
pack b
x, (Bool
True, b -> a
pack (b
yb -> b -> b
forall a. Num a => a -> a -> a
-b
x)))
else (b -> a
pack b
y, (Bool
False, b -> a
pack (b
xb -> b -> b
forall a. Num a => a -> a -> a
-b
y)))
zero :: C a => a
zero :: forall a. C a => a
zero = a
forall a. Monoid a => a
Monoid.mempty
infixl 6 `add`
add :: C a => a -> a -> a
add :: forall a. C a => a -> a -> a
add = a -> a -> a
forall a. Monoid a => a -> a -> a
Monoid.mappend
sum :: C a => [a] -> a
sum :: forall a. C a => [a] -> a
sum = [a] -> a
forall a. Monoid a => [a] -> a
Monoid.mconcat
maximum :: C a => [a] -> a
maximum :: forall a. C a => [a] -> a
maximum = (a -> a -> a) -> a -> [a] -> a
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl a -> a -> a
forall a. Ord a => a -> a -> a
max a
forall a. C a => a
zero
switchDifferenceNegative ::
C a =>
a -> a -> (a -> b) -> (a -> b) -> b
switchDifferenceNegative :: forall a b. C a => a -> a -> (a -> b) -> (a -> b) -> b
switchDifferenceNegative a
x a
y a -> b
branchXminusY a -> b
branchYminusX =
let (Bool
b,a
d) = (a, (Bool, a)) -> (Bool, a)
forall a b. (a, b) -> b
snd ((a, (Bool, a)) -> (Bool, a)) -> (a, (Bool, a)) -> (Bool, a)
forall a b. (a -> b) -> a -> b
$ a -> a -> (a, (Bool, a))
forall a. C a => a -> a -> (a, (Bool, a))
split a
y a
x
in if Bool
b
then a -> b
branchXminusY a
d
else a -> b
branchYminusX a
d
switchDifferenceOrdering ::
C a =>
a -> a -> b -> (a -> b) -> (a -> b) -> b
switchDifferenceOrdering :: forall a b. C a => a -> a -> b -> (a -> b) -> (a -> b) -> b
switchDifferenceOrdering a
x a
y b
branchZero a -> b
branchXminusY a -> b
branchYminusX =
let (Bool
b,a
d) = (a, (Bool, a)) -> (Bool, a)
forall a b. (a, b) -> b
snd ((a, (Bool, a)) -> (Bool, a)) -> (a, (Bool, a)) -> (Bool, a)
forall a b. (a -> b) -> a -> b
$ a -> a -> (a, (Bool, a))
forall a. C a => a -> a -> (a, (Bool, a))
split a
y a
x
in if Bool
b
then
if a
da -> a -> Bool
forall a. Eq a => a -> a -> Bool
==a
forall a. C a => a
zero
then b
branchZero
else a -> b
branchXminusY a
d
else a -> b
branchYminusX a
d
(-|) :: C a => a -> a -> a
a
x -| :: forall a. C a => a -> a -> a
-| a
y =
let (Bool
b,a
d) = (a, (Bool, a)) -> (Bool, a)
forall a b. (a, b) -> b
snd ((a, (Bool, a)) -> (Bool, a)) -> (a, (Bool, a)) -> (Bool, a)
forall a b. (a -> b) -> a -> b
$ a -> a -> (a, (Bool, a))
forall a. C a => a -> a -> (a, (Bool, a))
split a
y a
x
in if Bool
b then a
d else a
forall a. C a => a
zero