Skip to content

Instantly share code, notes, and snippets.

Last active March 16, 2021 15:51
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
type Food =
| Chicken
| Rice
type Step<'next> =
| GetFood of Food * 'next
| Eat of Food * 'next
| Sleep of hours:int * 'next
module Step =
let map f step =
match step with
| GetFood (food, next) -> GetFood (food, next |> f)
| Eat (food, next) -> Eat (food, next |> f)
| Sleep (hours, next) -> Sleep (hours, next |> f)
type Plan<'t> =
| Do of Step<Plan<'t>>
| Return of 't
let getFood () =
let randomFood = Food.Chicken
Do (GetFood (randomFood, Return randomFood))
let eat food =
Do (Eat (food, Return ()))
let sleep length =
Do (Sleep (length, Return ()))
module Plan =
let rec bind f plan =
match plan with
| Do steps ->
|> (bind f)
|> Do
| Return value -> f value
type PlanBuilder () =
member this.Return v = Return v
member this.ReturnFrom mv = mv
member this.Zero () = Return ()
member this.Bind (v, f) = Plan.bind f v
let plan = PlanBuilder ()
let myPlan =
plan {
let! food = getFood ()
do! sleep 10
do! eat food
Copy link

matthewcrews commented Mar 16, 2021

The example is silly but it illustrates what I'm trying to accomplish. Ultimately, I want to be able to generate a Plan which could have many steps. The simulation executes the steps in the plan according to rules of what is available when.

My main challenge is on lines 54-56. I want to capture which food was obtained so that when an interpreter runs the plan, it knows which food to consume.

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