Skip to content

Instantly share code, notes, and snippets.

Embed
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 ->
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