module Data.Transaction
(
action
, reduce
, toList
, tMap
, tFilter
, tFilterMap
, Transaction
, TransactionM
) where
data TransactionM a x
= TVal a (TransactionM a x)
| TNull x
deriving (Functor)
type Transaction a = TransactionM a ()
instance Applicative (TransactionM a) where
pure = TNull
TVal a next <*> f = TVal a (next <*> f)
TNull g <*> f = f >>= (pure . g)
instance Monad (TransactionM a) where
return = pure
TVal a next >>= f = TVal a (next >>= f)
TNull a >>= f = f a
action :: a -> Transaction a
action a = TVal a $ pure ()
tMap :: (a -> b) -> Transaction a -> Transaction b
tMap f = tFilterMap (pure . f)
tFilter :: (a -> Bool) -> Transaction a -> Transaction a
tFilter p = tFilterMap $ \a ->
if p a
then Just a
else Nothing
tFilterMap :: (a -> Maybe b) -> Transaction a -> Transaction b
tFilterMap f (TVal a next) =
case f a of
Just b ->
TVal b $ tFilterMap f next
Nothing ->
tFilterMap f next
tFilterMap _ (TNull ()) = TNull ()
reduce :: (b -> a -> b) -> b -> Transaction a -> b
reduce f b (TVal a next) = reduce f (f b a) next
reduce _ b (TNull ()) = b
toList :: Transaction a -> [a]
toList trans = reduce (\f a -> f . (a:)) id trans []