我正在尝试弄清楚如何使用计算构建器来表示一组延迟的嵌套步骤。
到目前为止,我有以下内容:
type Entry =
| Leaf of string * (unit -> unit)
| Node of string * Entry list * (unit -> unit)
type StepBuilder(desc:string) =
member this.Zero() = Leaf(desc,id)
member this.Bind(v:string, f:unit->string) =
Node(f(), [Leaf(v,id)], id)
member this.Bind(v:Entry, f:unit->Entry) =
match f() with
| Node(label,children,a) -> Node(label, v :: children, a)
| Leaf(label,a) -> Node(label, [v], a)
let step desc = StepBuilder(desc)
let a = step "a" {
do! step "b" {
do! step "c" {
do! step "c.1" {
// todo: this still evals as it goes; need to find a way to defer
// the inner contents...
printfn "TEST"
}
}
}
do! step "d" {
printfn "d"
}
}
这会产生所需的结构:
A(B(C(c.1)), D)
我的问题是,在构建结构时,printfn
需要调用。
理想情况下,我想要的是能够检索树结构,但能够调用一些返回的函数,然后执行内部块。
我意识到这意味着如果你有两个嵌套的步骤,它们之间有一些“正常”代码,它需要能够读取步骤声明,然后调用它(如果这有意义的话?)。
我知道这一点,Delay
并且Run
是用于计算表达式的延迟执行的东西,但我不确定它们在这里是否对我有帮助,因为不幸的是它们会评估所有内容。
我很可能遗漏了一些非常明显且非常“实用”的东西,但我似乎无法让它做我想做的事。
澄清
我id
用于演示,它们是拼图的一部分,我想象我可能如何呈现我想要的表达的“可调用”部分。