F# quotations: variable may escape scope

浪尽此生 提交于 2019-12-04 08:23:52

F# quotation syntax doesn't support variables that could potentially escape the scope, so you'll need to construct the tree explicitly using the Expr operations. Something like this should do the trick:

open Microsoft.FSharp.Quotations

let rec h n (z:Expr<int>) = 
  if n = 0 then z                
  else 
    let v = new Var("x", typeof<int>)
    let ve = Expr.Var(v)
    Expr.Cast<int>
        (Expr.Application( Expr.Lambda(v, h (n - 1) <@ %%ve + %z @>), 
                           Expr.Value(n)))

However, this is quite artificial example (to demonstrate variable capturing in MetaOCaml, which isn't available in F#). It just generates expression like (2 + (1 + ...)). You can get the same result by writing something like this:

let rec h n (z:Expr<int>) = 
  if n = 0 then z                
  else h (n - 1) <@ n + %z @>

Or even better:

[ 1 .. 4 ] |> List.fold (fun st n -> <@ n + %st @>) <@ 0 @>

I also came accross this limitation in F# quotations and it would be nice if this was supported. However, I don't think it is such a big problem in practice, because F# quotations are not used for staged meta-programming. They are more useful for analyzing existing F# code than for generating code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!