f# 3.0 - F# laziness in quoted computation expressions -
using quote member on computation expression convert workflow ast, such getenumerator()
not called on sequence quotation constructed (i.e., have form of laziness). in use case, sequence represents remote data-source, , invoking getenumerator()
member on go out , query against it.
is there way implicitly use lazy type (and still use quote member) on source member not eagerly call
getenumerator()
, instead has not loaded value yet?why let binding defined property of module , variable within function treated different entities in quotation, i.e.
propertyget
vsvalue
.
some test code...
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 { x in bar () } let insidelet() = let bar = [1; 2; 3] foo { x in bar () } insidelet()
which results in following 2 quotations
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, []))))])
is there way implicitly use lazy type (and still use quote member) on source member not eagerly call getenumerator() , instead has not loaded value yet?
i don't think there way implicitly use lazy type. however, not quite understand question - when use quote
method, can perform transformation on quotation get, can transform quotation not call getenumerator
member (of course, you'll have replace wiht else returns data...)
the key thing building query not call getenumerator
method. should able quotation & transform & evaluate without calling getenumerator
.
why let binding defined property of module , variable within function treated different entities in quotation, i.e.
propertyget
vsvalue
.
a let binding in module compiled static member , quotation captures reference static member. local variables, capturing references not possible, value
node embeds data directly quotation. (you write transformation turns propertyget
value
getting current value property)
edit: when create ienumerable
throws when getenumerator
called, printed quotation in f# interactive shows error (because f# interactive tries evaluate sequence output first few members), quotation contains source value
.
if remove run
method builder (so returns quotation), should work (and return "fancy source" string):
type fancysource() = member x.source = "fancy source" interface seq<int> member x.getenumerator() = failwith "!" interface system.collections.ienumerable member x.getenumerator() = failwith "!" let insidelet() = let bar = new fancysource() foo { x in bar () } match insidelet() | patterns.call(_, _, patterns.call(_, _, [patterns.value(:? fancysource v, _)])::_) -> v.source
Comments
Post a Comment