Skip to content

Instantly share code, notes, and snippets.

@matthewcrews
Last active March 16, 2021 15:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewcrews/084fbebda1b5d3fdf717b6c94a5789ba to your computer and use it in GitHub Desktop.
Save matthewcrews/084fbebda1b5d3fdf717b6c94a5789ba to your computer and use it in GitHub Desktop.
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 ->
steps
|> Step.map (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
}
@matthewcrews
Copy link
Author

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