这就是我想做的事情:
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#解释这个自定义操作确实应该接受计算表达式?
答案 0 :(得分:0)
我想有一种方法几乎可以获得你想要的语法。您使velocity
操作接受VelocityBuilder生成的类型 - 在您的情况下似乎是option
。然后创建一个单独的计算并将其传入。
所以你得到这样的东西:
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
})
}
也就是说,如果你打算编写计算工作流程,你可能应该首先设计一个类型来表示你的计算状态。现在你有语法糖,但没有肉;)
一旦你有了一个类型,如果它变得有用,工作流程可以跟着它。