F# 在单个seq表达式中混合seqbuilder[CustomOperation]属性方法和操作
此代码运行良好,除非我取消注释自定义seq表达式中的最后一行:F# 在单个seq表达式中混合seqbuilder[CustomOperation]属性方法和操作,f#,F#,此代码运行良好,除非我取消注释自定义seq表达式中的最后一行: type T (i: int) = member x.i = i override x.ToString() = sprintf "T is %A " x.i type TBuilder() = member x.Yield (()) = Seq.empty [<CustomOperation("test")>] member x.Test1 (source
type T (i: int) =
member x.i = i
override x.ToString() =
sprintf "T is %A " x.i
type TBuilder() =
member x.Yield (()) = Seq.empty
[<CustomOperation("test")>]
member x.Test1 (source : seq<_>, i: int) : seq<T> =
printfn "Calling Test1 with i= %d" i |> ignore
seq { yield! source
yield T(i) }
let t = TBuilder()
let mytest =
t {
test 42
test 43
// yield T(44) // if uncommented, it does not compile
}
我的问题:有混合的方法吗
- 我的[CustomOperation]测试(来自方法Test1),它生成T个对象
- 普通的收益率,例如
或任何其他与seq相关的语法收益率T(44)
谢谢。简短回答:不。如果您更改运算符以保留变量绑定(通过
maintansvariablespace=true
或maintansvariablespace使用[]
属性构造函数的Bind=true
参数),那么您将不需要进行,而是需要绑定
你认为你写的计算表达式是什么意思?如果你看看F#规范是如何为计算表达式指定翻译的,任何形式的
bldr {
op1 x
op2 y
yield z
}
会变成
bldr.For(bldr.Op2(bldr.Op1(bldr.Yield(), x), y), fun () -> b.Yield(z))
因此,您显然需要一个For
方法,而且您的Yield
方法需要做一些不同的事情;至少它需要能够接受任意类型的参数(例如,在上面的示例中,它需要处理unit
类型的参数,以及值z
具有的任何类型的参数)。为什么您的收益率成员要接受一个单位?我认为它应该取T值。@Bartek;在引用的参考文献中,产量的定义如下。它返回一个空的seq来初始化seq,然后Test1方法获取到目前为止生成的所有源代码,并添加另一个元素。
bldr.For(bldr.Op2(bldr.Op1(bldr.Yield(), x), y), fun () -> b.Yield(z))