Skip to content

Instantly share code, notes, and snippets.

@eddking
Created December 11, 2017 16:18
Show Gist options
  • Save eddking/bfd277eb4b3e95ba423a059f6c8f3638 to your computer and use it in GitHub Desktop.
Save eddking/bfd277eb4b3e95ba423a059f6c8f3638 to your computer and use it in GitHub Desktop.
Free monad example in purescript
module Main where
import Data.Generic
import Prelude
import Control.Monad.Free (Free, liftF, runFreeM)
import Control.Monad.Eff
import Control.Monad.Eff.Console (log, CONSOLE)
import Control.Monad.Eff.Random (randomBool, RANDOM)
data Action =
OverlayStatus |
Log |
GeoLocationSuccess
derive instance genericAction :: Generic Action
instance showAction :: Show Action where
show = gShow
type Predicate a = a -> Boolean
data Command a =
Take (Action -> a) |
Put Action a
derive instance functorCommand :: Functor Command
type Script a = Free Command a
put :: Action -> Script Unit
put a = liftF (Put a unit)
takeAny :: Script Action
takeAny = liftF (Take id)
take :: Predicate Action -> Script Action
take p = do
action <- takeAny
if p action
then pure action
else take p
isLog :: Predicate Action
isLog Log = true
isLog _ = false
main :: Script Action
main = do
action <- take isLog
put action
pure action
runScript script = (runFreeM interpretCommand) script
interpretCommand :: forall a. Command a -> Eff (console :: CONSOLE, random :: RANDOM) a
interpretCommand c = case c of
Take fun -> do
bool <- randomBool
let action = if bool then Log else OverlayStatus
log $ "Take " <> (show action)
pure $ fun action
Put action u -> do
log $ "Put " <> (show action)
pure u
@willfrew
Copy link

> runScript main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment