A simple CRUD DSL example with an asynchronious interpreter written as Cofree
Clone or download
Marcin Szamotulski
Marcin Szamotulski update .gitignore
Latest commit 9c26a8d Apr 25, 2017
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src add getUser command Apr 25, 2017
.gitignore update .gitignore Apr 25, 2017
LICENSE.md Update LICENSE.md Mar 12, 2017
README.md update README.md Mar 16, 2017
bower.json purescript-0.11 Apr 10, 2017

README.md

A simple crud DSL with an interpreter written as cofree commonad in Purescript

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 and Cofree using the explore function from Control.Comonad.Cofree module.

  • asynchronous one with computations in the Aff monad

    newtype 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.