The store type is simply
type Store = Array User
where
newtype User = User
{ id :: Int
, name :: String
}
There are four commands in the DSL:
data Command a = Add User a
| Remove Int a
| ChangeName Int String a
| GetUsers (Array User -> a)
| SaveUser User a
The type of the DSL is
type StoreDSL a = Free Command a
There are two interpreters
-
synchronous one
newtype Run a = Run { addUser :: User -> a , remove :: Int -> a , changeName :: Int -> String -> a , getUsers :: Unit -> Tuple (Array User) a , saveUser :: User -> a } type Interp a = Cofree Run a
The pairing is given by
pair :: forall x y. Command (x -> y) -> Run x -> y
We pair the
Free
andCofree
using theexplore
function fromControl.Comonad.Cofree
module. -
asynchronous one with computations in the
Aff
monadnewtype RunAff eff a = RunAff { addUser :: User -> Aff eff a , remove :: Int -> Aff eff a , changeName :: Int -> String -> Aff eff a , getUsers :: Unit -> Aff eff (Tuple (Array User) a) , saveUser :: User -> Aff eff a } type AffInterp eff a = Cofree (RunAff eff) a
The pairing is given by
pairInAff :: forall eff x y. Command (x -> y) -> RunAff eff x -> Aff eff y
Here we pair using a custom
exploreAff
function.