{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Data.Tax
(
Tax(..)
, MoneyTax
, lump
, flat
, threshold
, threshold'
, thresholds
, above
, above'
, marginal
, lesserOf
, greaterOf
, limit
, effective
, module Data.Money
, Semigroup(..)
, Monoid(..)
, Profunctor(..)
) where
import Data.Profunctor (Profunctor(..))
import Data.Semigroup (Semigroup(..))
import Data.Money
newtype Tax a b = Tax { forall a b. Tax a b -> a -> b
getTax :: a -> b }
deriving (NonEmpty (Tax a b) -> Tax a b
Tax a b -> Tax a b -> Tax a b
(Tax a b -> Tax a b -> Tax a b)
-> (NonEmpty (Tax a b) -> Tax a b)
-> (forall b. Integral b => b -> Tax a b -> Tax a b)
-> Semigroup (Tax a b)
forall b. Integral b => b -> Tax a b -> Tax a b
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall a b. Semigroup b => NonEmpty (Tax a b) -> Tax a b
forall a b. Semigroup b => Tax a b -> Tax a b -> Tax a b
forall a b b. (Semigroup b, Integral b) => b -> Tax a b -> Tax a b
$c<> :: forall a b. Semigroup b => Tax a b -> Tax a b -> Tax a b
<> :: Tax a b -> Tax a b -> Tax a b
$csconcat :: forall a b. Semigroup b => NonEmpty (Tax a b) -> Tax a b
sconcat :: NonEmpty (Tax a b) -> Tax a b
$cstimes :: forall a b b. (Semigroup b, Integral b) => b -> Tax a b -> Tax a b
stimes :: forall b. Integral b => b -> Tax a b -> Tax a b
Semigroup, Semigroup (Tax a b)
Tax a b
Semigroup (Tax a b) =>
Tax a b
-> (Tax a b -> Tax a b -> Tax a b)
-> ([Tax a b] -> Tax a b)
-> Monoid (Tax a b)
[Tax a b] -> Tax a b
Tax a b -> Tax a b -> Tax a b
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall a b. Monoid b => Semigroup (Tax a b)
forall a b. Monoid b => Tax a b
forall a b. Monoid b => [Tax a b] -> Tax a b
forall a b. Monoid b => Tax a b -> Tax a b -> Tax a b
$cmempty :: forall a b. Monoid b => Tax a b
mempty :: Tax a b
$cmappend :: forall a b. Monoid b => Tax a b -> Tax a b -> Tax a b
mappend :: Tax a b -> Tax a b -> Tax a b
$cmconcat :: forall a b. Monoid b => [Tax a b] -> Tax a b
mconcat :: [Tax a b] -> Tax a b
Monoid, (forall a b. (a -> b) -> Tax a a -> Tax a b)
-> (forall a b. a -> Tax a b -> Tax a a) -> Functor (Tax a)
forall a b. a -> Tax a b -> Tax a a
forall a b. (a -> b) -> Tax a a -> Tax a b
forall a a b. a -> Tax a b -> Tax a a
forall a a b. (a -> b) -> Tax a a -> Tax a b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a a b. (a -> b) -> Tax a a -> Tax a b
fmap :: forall a b. (a -> b) -> Tax a a -> Tax a b
$c<$ :: forall a a b. a -> Tax a b -> Tax a a
<$ :: forall a b. a -> Tax a b -> Tax a a
Functor, (forall a b c d. (a -> b) -> (c -> d) -> Tax b c -> Tax a d)
-> (forall a b c. (a -> b) -> Tax b c -> Tax a c)
-> (forall b c a. (b -> c) -> Tax a b -> Tax a c)
-> (forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> Tax a b -> Tax a c)
-> (forall a b c (q :: * -> * -> *).
Coercible b a =>
Tax b c -> q a b -> Tax a c)
-> Profunctor Tax
forall a b c. (a -> b) -> Tax b c -> Tax a c
forall b c a. (b -> c) -> Tax a b -> Tax a c
forall a b c d. (a -> b) -> (c -> d) -> Tax b c -> Tax a d
forall a b c (q :: * -> * -> *).
Coercible b a =>
Tax b c -> q a b -> Tax a c
forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> Tax a b -> Tax a c
forall (p :: * -> * -> *).
(forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d)
-> (forall a b c. (a -> b) -> p b c -> p a c)
-> (forall b c a. (b -> c) -> p a b -> p a c)
-> (forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> p a b -> p a c)
-> (forall a b c (q :: * -> * -> *).
Coercible b a =>
p b c -> q a b -> p a c)
-> Profunctor p
$cdimap :: forall a b c d. (a -> b) -> (c -> d) -> Tax b c -> Tax a d
dimap :: forall a b c d. (a -> b) -> (c -> d) -> Tax b c -> Tax a d
$clmap :: forall a b c. (a -> b) -> Tax b c -> Tax a c
lmap :: forall a b c. (a -> b) -> Tax b c -> Tax a c
$crmap :: forall b c a. (b -> c) -> Tax a b -> Tax a c
rmap :: forall b c a. (b -> c) -> Tax a b -> Tax a c
$c#. :: forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> Tax a b -> Tax a c
#. :: forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> Tax a b -> Tax a c
$c.# :: forall a b c (q :: * -> * -> *).
Coercible b a =>
Tax b c -> q a b -> Tax a c
.# :: forall a b c (q :: * -> * -> *).
Coercible b a =>
Tax b c -> q a b -> Tax a c
Profunctor)
type MoneyTax a = Tax (Money a) (Money a)
above :: (Num a, Ord a) => Money a -> a -> Tax (Money a) (Money a)
above :: forall a. (Num a, Ord a) => Money a -> a -> Tax (Money a) (Money a)
above Money a
l = Money a -> Tax (Money a) (Money a) -> Tax (Money a) (Money a)
forall b a.
(Num b, Ord b) =>
Money b -> Tax (Money b) a -> Tax (Money b) a
above' Money a
l (Tax (Money a) (Money a) -> Tax (Money a) (Money a))
-> (a -> Tax (Money a) (Money a)) -> a -> Tax (Money a) (Money a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Tax (Money a) (Money a)
forall a. Num a => a -> Tax (Money a) (Money a)
flat
above' :: (Num b, Ord b) => Money b -> Tax (Money b) a -> Tax (Money b) a
above' :: forall b a.
(Num b, Ord b) =>
Money b -> Tax (Money b) a -> Tax (Money b) a
above' Money b
l = (Money b -> Money b) -> Tax (Money b) a -> Tax (Money b) a
forall a b c. (a -> b) -> Tax b c -> Tax a c
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> p b c -> p a c
lmap (\Money b
x -> Money b -> Money b -> Money b
forall a. Ord a => a -> a -> a
max (Money b
x Money b -> Money b -> Money b
forall a. Num a => Money a -> Money a -> Money a
$-$ Money b
l) Money b
forall a. Monoid a => a
mempty)
marginal :: (Num a, Ord a) => [(Money a, a)] -> Tax (Money a) (Money a)
marginal :: forall a.
(Num a, Ord a) =>
[(Money a, a)] -> Tax (Money a) (Money a)
marginal = ((Money a, a) -> Tax (Money a) (Money a))
-> [(Money a, a)] -> Tax (Money a) (Money a)
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((Money a -> a -> Tax (Money a) (Money a))
-> (Money a, a) -> Tax (Money a) (Money a)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Money a -> a -> Tax (Money a) (Money a)
forall a. (Num a, Ord a) => Money a -> a -> Tax (Money a) (Money a)
above)
lump :: a -> Tax b a
lump :: forall a b. a -> Tax b a
lump = (b -> a) -> Tax b a
forall a b. (a -> b) -> Tax a b
Tax ((b -> a) -> Tax b a) -> (a -> b -> a) -> a -> Tax b a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b -> a
forall a b. a -> b -> a
const
flat :: (Num a) => a -> Tax (Money a) (Money a)
flat :: forall a. Num a => a -> Tax (Money a) (Money a)
flat = (Money a -> Money a) -> Tax (Money a) (Money a)
forall a b. (a -> b) -> Tax a b
Tax ((Money a -> Money a) -> Tax (Money a) (Money a))
-> (a -> Money a -> Money a) -> a -> Tax (Money a) (Money a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Money a -> Money a
forall a. Num a => a -> Money a -> Money a
(*$)
threshold :: (Num a, Ord a) => Money a -> a -> Tax (Money a) (Money a)
threshold :: forall a. (Num a, Ord a) => Money a -> a -> Tax (Money a) (Money a)
threshold Money a
l = Money a -> Tax (Money a) (Money a) -> Tax (Money a) (Money a)
forall b a. (Ord b, Monoid a) => b -> Tax b a -> Tax b a
threshold' Money a
l (Tax (Money a) (Money a) -> Tax (Money a) (Money a))
-> (a -> Tax (Money a) (Money a)) -> a -> Tax (Money a) (Money a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Tax (Money a) (Money a)
forall a. Num a => a -> Tax (Money a) (Money a)
flat
threshold' :: (Ord b, Monoid a) => b -> Tax b a -> Tax b a
threshold' :: forall b a. (Ord b, Monoid a) => b -> Tax b a -> Tax b a
threshold' b
l Tax b a
tax = (b -> a) -> Tax b a
forall a b. (a -> b) -> Tax a b
Tax (\b
x -> if b
x b -> b -> Bool
forall a. Ord a => a -> a -> Bool
>= b
l then Tax b a -> b -> a
forall a b. Tax a b -> a -> b
getTax Tax b a
tax b
x else a
forall a. Monoid a => a
mempty)
thresholds :: (Num a, Ord a) => [(Money a, a)] -> Tax (Money a) (Money a)
thresholds :: forall a.
(Num a, Ord a) =>
[(Money a, a)] -> Tax (Money a) (Money a)
thresholds = ((Money a, a) -> Tax (Money a) (Money a))
-> [(Money a, a)] -> Tax (Money a) (Money a)
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((Money a -> a -> Tax (Money a) (Money a))
-> (Money a, a) -> Tax (Money a) (Money a)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Money a -> a -> Tax (Money a) (Money a)
forall a. (Num a, Ord a) => Money a -> a -> Tax (Money a) (Money a)
threshold)
lesserOf :: (Ord a) => Tax b a -> Tax b a -> Tax b a
lesserOf :: forall a b. Ord a => Tax b a -> Tax b a -> Tax b a
lesserOf Tax b a
t1 Tax b a
t2 = (b -> a) -> Tax b a
forall a b. (a -> b) -> Tax a b
Tax (\b
x -> a -> a -> a
forall a. Ord a => a -> a -> a
min (Tax b a -> b -> a
forall a b. Tax a b -> a -> b
getTax Tax b a
t1 b
x) (Tax b a -> b -> a
forall a b. Tax a b -> a -> b
getTax Tax b a
t2 b
x))
greaterOf :: (Ord a) => Tax b a -> Tax b a -> Tax b a
greaterOf :: forall a b. Ord a => Tax b a -> Tax b a -> Tax b a
greaterOf Tax b a
t1 Tax b a
t2 = (b -> a) -> Tax b a
forall a b. (a -> b) -> Tax a b
Tax (\b
x -> a -> a -> a
forall a. Ord a => a -> a -> a
max (Tax b a -> b -> a
forall a b. Tax a b -> a -> b
getTax Tax b a
t1 b
x) (Tax b a -> b -> a
forall a b. Tax a b -> a -> b
getTax Tax b a
t2 b
x))
limit :: (Ord a) => a -> Tax b a -> Tax b a
limit :: forall a b. Ord a => a -> Tax b a -> Tax b a
limit = Tax b a -> Tax b a -> Tax b a
forall a b. Ord a => Tax b a -> Tax b a -> Tax b a
lesserOf (Tax b a -> Tax b a -> Tax b a)
-> (a -> Tax b a) -> a -> Tax b a -> Tax b a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Tax b a
forall a b. a -> Tax b a
lump
effective
:: (Fractional a)
=> Money a -> Tax (Money a) (Money a) -> Tax (Money a) (Money a)
effective :: forall a.
Fractional a =>
Money a -> Tax (Money a) (Money a) -> Tax (Money a) (Money a)
effective Money a
x Tax (Money a) (Money a)
tax = a -> Tax (Money a) (Money a)
forall a. Num a => a -> Tax (Money a) (Money a)
flat (Tax (Money a) (Money a) -> Money a -> Money a
forall a b. Tax a b -> a -> b
getTax Tax (Money a) (Money a)
tax Money a
x Money a -> Money a -> a
forall a. Fractional a => Money a -> Money a -> a
$/$ Money a
x)