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.

  1. 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?

  2. why let binding defined property of module , variable within function treated different entities in quotation, i.e. propertyget vs value.

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 vs value.

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

Popular posts from this blog

java - Run a .jar on Heroku -

java - Jtable duplicate Rows -

validation - How to pass paramaters like unix into windows batch file -