This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.