F# 我可以为构建器(如DSL)创建嵌套计算表达式吗?

F# 我可以为构建器(如DSL)创建嵌套计算表达式吗?,f#,dsl,computation-expression,F#,Dsl,Computation Expression,这就是我想做的: type DirectionBuilder() = member self.Yield(()) = [] [<CustomOperation("left")>] member self.Left (acc, degree) = None [<CustomOperation("right")>] member self.Right (acc, degree) = None [<CustomOpe

这就是我想做的:

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
    }
}

有没有办法向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
    })
}
type DirectionBuilder()=
成员自身收益率(())=[]
[]
左侧成员自身(acc,学位)=无
[]
成员自身权利(acc,学位)=无
[]
成员自身速度(acc,奇数:'a选项)=无
键入VelocityBuilder()=
成员自身收益率(())=[]
[]
成员自加速(acc,v)=无
[]
构件自身减速(acc,v)=无
let dir=new DirectionBuilder()
设vel=new VelocityBuilder()
迪尔{
对90
左30
速度(vel){
加速1
})
}
这就是说,如果您开始编写计算工作流,那么您可能应该首先设计一个类型来表示您的计算状态。现在你有糖,但没有肉;)

一旦你有了一个类型,如果它被证明是有用的,那么一个工作流就可以从中产生

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
    })
}