【发布时间】:2021-03-17 21:20:03
【问题描述】:
我正在尝试使用计算表达式来构建操作列表。我需要绑定到从 getFood 操作返回的值,以便我可以注册稍后的步骤来使用它。
type Food =
| Chicken
| Rice
type Step =
| GetFood of Food
| Eat of Food
| Sleep of duration:int
type Plan = Plan of Step list
type PlanBuilder () =
member this.Bind (plan:Plan, f) =
f plan
member this.Yield _ = Plan []
member this.Run (Plan x) = Plan (List.rev x)
[<CustomOperation("eat")>]
member this.Eat (Plan p, food) =
printfn "Eat"
Plan ((Eat food)::p)
[<CustomOperation("sleep")>]
member this.Sleep (Plan p, duration) =
printfn "Sleep"
Plan ((Sleep duration)::p)
let plan = PlanBuilder()
let rng = System.Random(123)
let getFood (Plan p) =
printfn "GetFood"
let randomFood =
if rng.NextDouble() > 0.5 then
Food.Chicken
else
Food.Rice
(Plan ((GetFood randomFood)::p)), randomFood
let testPlan =
plan {
let! food = getFood // <-- This is what I am trying to get to work
sleep 10
eat food
}
我认为问题出在Bind,但我不知道是什么问题。
(*
Example result
testPlan =
(GetFood Chicken,(
(Sleep 10,(
EatFood Chicken
))
))
*)
【问题讨论】:
-
你不必为let 中的getFood 提供参数!线?也许是一个空的计划?
-
我认为 Bind 函数可以做到这一点
标签: f# monads computation-expression