【问题标题】:Dynamic Lookup in F#F# 中的动态查找
【发布时间】:2017-02-18 01:24:36
【问题描述】:

有人可以帮我写 Tomas Petricek 的文章吗:http://tomasp.net/blog/fsharp-dynamic-lookup.aspx/#dynfslinks? 问题是它已经严重过时了。我理解命名空间

open Microsoft.FSharp.Quotations.Typed
open Microsoft.FSharp.Quotations.Raw

没了。所以我删除了开口。但是仍然有错误。 “类型化”未定义。 “RecdGet”未定义。我怀疑他们不是最后一个。我试图向我的老板证明 F# 可以很好地用于数据库规范化。字段的动态查找确实有助于我处理具有不同前缀的类似名称的字段。

在 fpish 上也有 Tomas 的帖子:https://fpish.net/topic/None/57493,据我所知是在文章之前

【问题讨论】:

  • 您在寻找这样的东西吗? stackoverflow.com/questions/17640218/…
  • @mydogisbox,是的,但我希望静态检查访问权限。所以,如果属性不存在,我会得到编译错误。据我了解,托马斯的解决方案就是这样做的。

标签: f# quotations


【解决方案1】:

这是一个粗略的等价物:

open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns

type DynamicMember<'t,'u> = Expr<'t -> 'u>

let getValueReader (expr:DynamicMember<'recdT, 'fieldT>) = 
  // Match the quotation representing the symbol
  match expr with
  | Lambda(v, PropertyGet (Some (Var v'), pi, [])) when v = v' ->
      // It represents reading of the F# record field..
      // .. get a function that reads the record field using F# reflection
      let rdr = Reflection.FSharpValue.PreComputeRecordFieldReader pi

      // we're not adding any additional processing, so we just
      // simply add type conversion to the correct types & return it
      ((box >> rdr >> unbox) : 'recdT -> 'fieldT)
  | _ -> 
      // Quotation doesn't represent symbol - this is an error
      failwith "Invalid expression - not reading record field!"

type SampleRec = { Str : string; Num : int }

let readStrField = getValueReader <@ fun (r : SampleRec) -> r.Str @>
let readNumField = getValueReader <@ fun (r : SampleRec) -> r.Num @>   

let rc = { Str = "Hello world!"; Num = 42 }
let s, n = readStrField rc, readNumField rc

printfn "Extracted: %s, %d" s n

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    • 2011-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多