module Control.InjFun (
InjFun
, cfapply
, inject
, (|->)
, explode
, merge
) where
newtype InjFun i c m o = InjFun {
cfapply :: i -> c -> m o
}
inject :: (i -> c -> m o) -> InjFun i c m o
inject f = InjFun f
(|->) :: (Monad m) => InjFun i c m o
-> InjFun o c' m o'
-> InjFun i (c,c') m o'
f |-> g = InjFun $ \i (c,c') -> do
r0 <- cfapply f i c
cfapply g r0 c'
explode :: (Monad m) => InjFun i c m (o0,o1)
-> (InjFun i c m o0,InjFun i c m o1)
explode f = (f',f'')
where f' = cf fst
f'' = cf snd
cf sel = InjFun $ \i c -> cfapply f i c >>= return . sel
merge :: (Monad m) => InjFun i c m o
-> InjFun i' c' m o'
-> InjFun (i,i') (c,c') m (o,o')
merge f g = fg
where fg = InjFun $ \(i,i') (c,c') -> do
r0 <- cfapply f i c
r1 <- cfapply g i' c'
return (r0,r1)