Skip to content

Instantly share code, notes, and snippets.

@willtim
Created December 13, 2012 21:30
Show Gist options
  • Save willtim/4280132 to your computer and use it in GitHub Desktop.
Save willtim/4280132 to your computer and use it in GitHub Desktop.
A Bot monad which provides a reader environment with suspended steps yielding Command values
module Process where
import Control.Monad.Reader
import Control.Monad.Cont
-- | this is the infinite stream of steps from the Bot, each step takes an environment
-- and yields a command and the entire rest of the computation
type Process = Reader DashBoard Step
data Step = Step { stepCmd :: Command, stepNext :: Process }
-- | start the process. transforms a Bot into a Process (a simple automaton)
start :: Bot a -> Process
start bot = runContT bot $ const . fix $ return . Step NoAction
yield :: Command -> Bot ()
yield cmd = ContT $ \c -> return $ Step cmd (c ())
type Bot = ContT Step (Reader DashBoard)
data Command = NoAction
| Fire
| Accelerate Double
deriving Show
-- | this is the dashboard of readings, ie. the bots view
-- the bot is provided a new set of readings every step
data DashBoard = DashBoard { vel :: Double } -- TODO this just has a dummy value for now
-- | runs the process for one step, requires the dashboard for this process
step :: DashBoard -> Process -> Step
step dash proc = runReader proc dash
bot1 :: Bot ()
bot1 = do
yield Fire
readings <- ask
yield $ Accelerate $ vel readings
yield Fire
-- A single step
proc1 = step (DashBoard 0) $ start bot1
test1 = stepCmd $ proc1
-- another step
test2 = stepCmd . step (DashBoard 0.5) $ stepNext proc1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment