如何在计算表达式中使用自定义操作从构建器访问值
How to Access a Value from a Builder using Custom Operation in a Computation Expression
我有一个计算表达式生成器,它接收
构造期间的值
type SomeBuilder<'e> (e: 'e) =
member this.Bind(x, fn) = ...
member this.Return x = ...
member this.ReturnFrom x = ...
let buildSome v = SomeBuilder(v)
buildSome 2 {
return 1
}
现在我想从
通过自定义操作的计算表达式
buildSome 2 {
return 1 + e()
}
所以我真的很想访问底层构建器对象中的 properties/values 并使用它们
我想我需要这样的东西
type SomeBuilder<'e> (e: 'e) =
member this.Bind(x, fn) = ...
member this.Return x = ...
member this.ReturnFrom x = ...
[<CustomOperation("e")>]
member this.E () = e
但这不起作用。
所以我的问题是
a) 使用 CustomOperations 和 Computational Expressions 是可能的
b) 如果可能的话,怎么做?
免责声明:
像往常一样,在编程中有一百万种方法可以达到类似的效果
以完全不同的方式。我明确要求这种特殊方式
如果答案只是 "No",我也可以。但请避免回答此处列出的最狭义的非答案。
我不确定您是否会喜欢我的回答以及它是否在您的范围内,但您可以使用如下技巧捕获构建器实例:
type SomeBuilder<'e> (e: 'e) =
member this.Value = e
[<CustomOperation("extract", MaintainsVariableSpaceUsingBind = true, AllowIntoPattern = true)>]
member this.Extract (state) = this
member this.Bind(x, fn) = fn x
member this.Return x = x
member this.ReturnFrom x = x
let builder e = new SomeBuilder<_>(e)
let x = builder 1 {
extract into builder // now we've brought builder in the scope
printfn "here we can read the value = %d" builder.Value
return 0
}
表明主构造函数参数在构建器实例方法的范围内:
type SomeBuilder<'e> (e: 'e) =
member __.Bind(x, fn) = fn x
member __.Return x = x
[<CustomOperation("e", MaintainsVariableSpaceUsingBind = true, AllowIntoPattern = true)>]
member __.E _ = e
SomeBuilder 2 {
e into i
return 1 + i }
// val it : int = 3
SomeBuilder "bar" {
e into s
return "foo" + s }
// val it : string = "foobar"
考虑自定义操作在构建器内部的位置;它会忽略它前面的表达式。
我有一个计算表达式生成器,它接收 构造期间的值
type SomeBuilder<'e> (e: 'e) =
member this.Bind(x, fn) = ...
member this.Return x = ...
member this.ReturnFrom x = ...
let buildSome v = SomeBuilder(v)
buildSome 2 {
return 1
}
现在我想从 通过自定义操作的计算表达式
buildSome 2 {
return 1 + e()
}
所以我真的很想访问底层构建器对象中的 properties/values 并使用它们
我想我需要这样的东西
type SomeBuilder<'e> (e: 'e) =
member this.Bind(x, fn) = ...
member this.Return x = ...
member this.ReturnFrom x = ...
[<CustomOperation("e")>]
member this.E () = e
但这不起作用。
所以我的问题是
a) 使用 CustomOperations 和 Computational Expressions 是可能的 b) 如果可能的话,怎么做?
免责声明:
像往常一样,在编程中有一百万种方法可以达到类似的效果
以完全不同的方式。我明确要求这种特殊方式
如果答案只是 "No",我也可以。但请避免回答此处列出的最狭义的非答案。
我不确定您是否会喜欢我的回答以及它是否在您的范围内,但您可以使用如下技巧捕获构建器实例:
type SomeBuilder<'e> (e: 'e) =
member this.Value = e
[<CustomOperation("extract", MaintainsVariableSpaceUsingBind = true, AllowIntoPattern = true)>]
member this.Extract (state) = this
member this.Bind(x, fn) = fn x
member this.Return x = x
member this.ReturnFrom x = x
let builder e = new SomeBuilder<_>(e)
let x = builder 1 {
extract into builder // now we've brought builder in the scope
printfn "here we can read the value = %d" builder.Value
return 0
}
表明主构造函数参数在构建器实例方法的范围内:
type SomeBuilder<'e> (e: 'e) =
member __.Bind(x, fn) = fn x
member __.Return x = x
[<CustomOperation("e", MaintainsVariableSpaceUsingBind = true, AllowIntoPattern = true)>]
member __.E _ = e
SomeBuilder 2 {
e into i
return 1 + i }
// val it : int = 3
SomeBuilder "bar" {
e into s
return "foo" + s }
// val it : string = "foobar"
考虑自定义操作在构建器内部的位置;它会忽略它前面的表达式。