module Data.HMemDb.RefConverter
(PreRefConv(PreRefConv, rcFrom, rcTo), RefConv(RefConv)) where
import Control.Applicative (Applicative(pure, (<*>)))
import Control.Monad (liftM2)
import Data.HMemDb.Bin (Bin, TableRefs(TRNil, TRPair))
import Data.HMemDb.MapTVar (MS)
data PreRefConv r input output =
PreRefConv {rcFrom :: input -> MS r, rcTo :: r -> MS output}
data RefConv input output where
RefConv :: Bin r => TableRefs r -> PreRefConv r input output -> RefConv input output
(|*|) ::
PreRefConv r1 input (middle -> output)
-> PreRefConv r2 input middle
-> PreRefConv (r1, r2) input output
p1 |*| p2 = PreRefConv from to where
from input = liftM2 (,) (rcFrom p1 input) (rcFrom p2 input)
to (r1, r2) = liftM2 ($) (rcTo p1 r1) (rcTo p2 r2)
instance Functor (RefConv input) where fmap h r = pure h <*> r
instance Applicative (RefConv input) where
pure output =
RefConv TRNil $
PreRefConv {rcFrom = const $ return (), rcTo = \ ~() -> return output}
RefConv trf pf <*> RefConv trx px = RefConv (TRPair trf trx) (pf |*| px)