計算式で Quote メンバーを使用してワークフローを AST に変換しますが、引用が構築されるときに が実際にはシーケンスで呼び出されないようにしたいと考えていますGetEnumerator()
(つまり、なんらかの形式の遅延があります)。私の使用例では、シーケンスはリモート データ ソースを表し、そのメンバーを呼び出すと、GetEnumerator()
実際に外部に出てクエリを実行します。
Source メンバーで暗黙的に Lazy 型を使用する (それでも Quote メンバーを使用する) 方法はあり
GetEnumerator()
ますか?let バインディングがモジュールのプロパティとして定義され、別の関数内の変数が引用符で異なるエンティティとして扱われるのはなぜですか、つまり
PropertyGet
vsValue
.
いくつかのテストコード...
module Example
open Microsoft.FSharp.Quotations
[<Interface>]
type I<'Type> =
inherit seq<'Type>
type FooBuilder() =
member __.Source (x : #seq<'Type>) : I<'Type> = invalidOp "not implemented"
member __.For (source : I<'Type>, f : 'Type -> I<'Type>) : I<'Type> = invalidOp "not implemented"
member __.Zero () : I<'Type> = invalidOp "not implemented"
member __.Quote (expr : Expr<#seq<'Type>>) = expr
member __.Run (expr : Expr<#seq<'Type>>) =
System.Console.WriteLine(expr)
let foo = FooBuilder()
let bar = [1; 2; 3]
foo {
for x in bar do ()
}
let insideLet() =
let bar = [1; 2; 3]
foo {
for x in bar do ()
}
insideLet()
その結果、次の 2 つの引用が得られます
Call (Some (Value (FSI_0009+FooBuilder)), For,
[Call (Some (Value (FSI_0009+FooBuilder)), Source,
[PropertyGet (None, bar, [])]),
Lambda (_arg1,
Let (x, _arg1,
Sequential (Value (<null>),
Call (Some (Value (FSI_0009+FooBuilder)), Zero,
[]))))])
Call (Some (Value (FSI_0009+FooBuilder)), For,
[Call (Some (Value (FSI_0009+FooBuilder)), Source, [Value ([1; 2; 3])]),
Lambda (_arg1,
Let (x, _arg1,
Sequential (Value (<null>),
Call (Some (Value (FSI_0009+FooBuilder)), Zero,
[]))))])