gpt4 book ai didi

f# - 我可以为 Builder Like DSL 创建嵌套的计算表达式吗?

转载 作者:行者123 更新时间:2023-12-05 05:25:55 25 4
gpt4 key购买 nike

这是我想做的:

type DirectionBuilder() =
member self.Yield(()) = []

[<CustomOperation("left")>]
member self.Left (acc, degree) = None

[<CustomOperation("right")>]
member self.Right (acc, degree) = None

[<CustomOperation("velocity")>]
member self.Velocity (acc, ()) = new VelocityBuilder()


and VelocityBuilder() =
member self.Yield(()) = []

[<CustomOperation("accelerate")>]
member self.Accesslarate (acc, v) = None

[<CustomOperation("decelerate")>]
member self.Decelerate (acc, v) = None


let direction () = new DirectionBuilder()

direction() {
right 90
left 30
velocity() {
accelerate 1
}
}

这行崩溃了

      velocity() {
----^^^^^^^^
stdin(952,5): error FS3099: 'velocity' is used with an incorrect number of
arguments. This is a custom operation in this query or computation
expression. Expected 1 argument(s), but given 2.
>

有没有办法向 F# 解释这个自定义操作确实应该接受一个计算表达式?

最佳答案

我想有一种方法几乎可以得到你想要的语法。您使 velocity 操作接受 VelocityBuilder 生成的类型 - 在您的情况下这似乎是一个 选项。然后创建一个单独的计算并将其传入。

所以你得到这样的东西:

type DirectionBuilder() =
member self.Yield(()) = []

[<CustomOperation("left")>]
member self.Left (acc, degree) = None

[<CustomOperation("right")>]
member self.Right (acc, degree) = None

[<CustomOperation("velocity")>]
member self.Velocity (acc, odd: 'a option) = None


type VelocityBuilder() =
member self.Yield(()) = []

[<CustomOperation("accelerate")>]
member self.Accelerate (acc, v) = None

[<CustomOperation("decelerate")>]
member self.Decelerate (acc, v) = None

let dir = new DirectionBuilder()
let vel = new VelocityBuilder()

dir {
right 90
left 30
velocity (vel {
accelerate 1
})
}

也就是说,如果您着手编写计算工作流,您可能应该首先设计一个类型来表示您的计算状态。现在你有语法糖,但没有肉 ;)

一旦您有了类型,如果它被证明是有用的,就可以遵循它的工作流程。

关于f# - 我可以为 Builder Like DSL 创建嵌套的计算表达式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28996554/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com