我正在创建一个建模DSL,希望能够创建一个
我无法弄清楚如何按预期工作。在代码示例底部提供了所需结果的示例。
Settings
构建器,并使用两个自定义操作:Buffer
和Constraint
,它们本身是计算表达式。原因是该领域具有重载的术语,而计算表达式允许您通过使用自定义操作来提供上下文。我无法弄清楚如何按预期工作。在代码示例底部提供了所需结果的示例。
type Buffer =
{
Name : string
Capacity : float
}
type Constraint =
{
Name : string
Limit : float
}
[<RequireQualifiedAccess>]
type Setting =
| Buffer of Buffer
| Constraint of Constraint
type BufferBuilder (name: string) =
member _.Yield _ : Buffer = { Name = name; Capacity = 0.0 }
member _.Run x : Buffer = x
[<CustomOperation("Capacity")>]
member _.Capacity (b: Buffer, newCapacity) =
{ b with Capacity = newCapacity }
let Buffer = BufferBuilder
type ConstraintBuilder (name: string) =
member _.Yield _ : Constraint = { Name = name; Limit = 0.0 }
member _.Run x : Constraint = x
[<CustomOperation("Limit")>]
member _.Limit (b: Constraint, newLimit) =
{ b with Limit = newLimit }
let Constraint = ConstraintBuilder
type SettingsBuilder () =
member _.Yield _ : Setting list = []
member _.Run x : Setting list = x
[<CustomOperation("Buffer")>]
member _.Buffer (settings, name: string, expr) =
// This does not work
let newSetting = BufferBuilder name expr
newSetting :: settings
[<CustomOperation("Constraint")>]
member _.Constraint (settings, name: string, expr) =
// This does not work
let newSetting = ConstraintBuilder name expr
newSetting :: settings
// The Computation Expression does not work
let mySettings =
SettingsBuilder {
Buffer "b1" {
Capacity 100.0
}
Constraint "c1" {
Limit 10.0
}
}
// Below shows that the desired outcome of `mySettings` would be
let b1 = { Name = "b1"; Capacity = 100.0 }
let c1 = { Name = "c1"; Limit = 10.0 }
let desiredSettings = [
Setting.Buffer b1
Setting.Constraint c1
]