module Data.Binding.Simple (module Data.Variable, Bindable, bind, Source) where
import Data.Variable
data Binding a = forall d t. Binding (a -> d) t (t -> d -> IO ())
data Source v a = Variable v => Source {bindings :: v [Binding a]
,var :: v a}
update' :: a -> Binding a -> IO ()
update' source (Binding extract target apply) = apply target $ extract source
update :: Source v a -> IO ()
update (Source bindings var) = do bindings <- readVar bindings
a <- readVar var
mapM_ (update' a) bindings
instance Variable v => Variable (Source v) where
newVar a = do bindings <- newVar []
v <- newVar a
return $ Source bindings v
readVar = readVar . var
writeVar s a = writeVar (var s) a >> update s
modifyVar s f = modifyVar (var s) f >> update s
modifyVar' s f = do b <- modifyVar' (var s) f
update s
return b
class Variable b => Bindable b where
bind :: b a
-> (a -> d)
-> t
-> (t -> d -> IO ())
-> IO ()
instance Variable v => Bindable (Source v) where
bind (Source bindings var) extract target apply =
do let binding = Binding extract target apply
a <- readVar var
update' a binding
modifyVar bindings (binding:)