Skip to content

Instantly share code, notes, and snippets.

@matthewcrews
Created March 17, 2021 05:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewcrews/2c6cc0b23003d598ae82489085c8d39a to your computer and use it in GitHub Desktop.
Save matthewcrews/2c6cc0b23003d598ae82489085c8d39a to your computer and use it in GitHub Desktop.
type StateId = StateId of int
type PlanId = PlanId of int
type StepId = StepId of int
type State = {
LastStateId : StateId
LastPlanId : PlanId
LastStepId : StepId
}
type Step =
| Eat of stepId: StepId * food:string
| Sleep of stepId: StepId * duration:int
type Plan = {
PlanId : PlanId
Steps : Step list
}
type PlanBuilder (state: State) =
let planId, newState =
let (PlanId lastPlanId) = state.LastPlanId
let nextPlanId = PlanId (lastPlanId + 1)
let newState = { state with LastPlanId = nextPlanId }
nextPlanId, newState
// member _.Yield _ = newState, { PlanId = planId; Steps = [] }
// member _.Run (state: State, steps: Step list) = state, { PlanId = planId; Steps = List.rev steps }
[<CustomOperation("close")>]
member _.Eat (steps: Step list, food: string) =
fun (state: State) ->
let (StepId lastStepId) = state.LastStepId
let nextStepId = StepId (lastStepId + 1)
let newState = { state with LastStepId = nextStepId }
let eatStep = Step.Eat (nextStepId, food)
newState, eatStep::steps
[<CustomOperation("sleep")>]
member _.Sleep (steps: Step list, duration: int) =
fun (state: State) ->
let (StepId lastStepId) = state.LastStepId
let nextStepId = StepId (lastStepId + 1)
let newState = { state with LastStepId = nextStepId }
let sleepStep = Step.Sleep (nextStepId, duration)
newState, sleepStep::steps
member _.Delay(f) =
fun (state: State) -> f state
let initialState = {
LastStateId = StateId 1
LastPlanId = PlanId 1
LastStepId = StepId 1
}
let plan, newState = PlanBuilder (initialState) {
eat "chicken"
sleep 10
eat "monkey"
}
let newState1, eatStep, remainingPlan = plan newState
let newState2, sleepStep, remainingPlan2 = remainingPlan newState1
let newState3, eatStep2, remainingPlan3 = remainingPlan2 newState2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment