首页 文章

我如何使用F#Reflection库?

提问于
浏览
3

我试图按照这个例子(来自Rob Pickering的"Foundations of F#"书的p137)但我无法使用最新的F#CTP .

我似乎错过了第3行的“ Value ”定义

Value.GetInfo(x)

这会产生:

错误FS0039:未定义名称空间或模块“值” .

任何人都可以告诉我这是来自哪里或新的语法是什么,如果现在这样做不同? (要温柔 - 这是我第一次玩F#)

以下是我工作的例子: -

#light
open Microsoft.FSharp.Reflection
let printTupleValues x =
    match Value.GetInfo(x) with
    | TupleValue vals ->
    print_string "("
    vals
    |> List.iteri
        (fun i v ->
            if i <> List.length vals - 1 then
                Printf.printf " %s, " (any_to_string v)
            else
                print_any v)
    print_string " )"
    | _ -> print_string "not a tuple"

printTupleValues ("hello world", 1)

3 回答

  • 0

    为Beta 1或CTP重写了F#反射库 . 这里是您的代码略微更改为使用新库,并避免使用F#PlusPack(print_string用于OCaml兼容性) .

    open Microsoft.FSharp.Reflection
    
    let printTupleValues x =
        if FSharpType.IsTuple( x.GetType() ) then
            let s =
                FSharpValue.GetTupleFields( x )
                |> Array.map (fun a -> a.ToString())
                |> Array.reduce (fun a b -> sprintf "%s, %s" a b)
            printfn "(%s)" s
        else 
            printfn "not a tuple"
    
    printTupleValues ("hello world", 1)
    
  • 4

    或者,如果您更喜欢使用匹配来分解元组,那么请使用活动模式尝试此操作 . 优点是您可以非常轻松地添加对其他类型的支持 .

    open Microsoft.FSharp.Reflection
    
    let (|ParseTuple|_|) = function
        | o when FSharpType.IsTuple( o.GetType() ) ->
            Some( FSharpValue.GetTupleFields(o) )
        | _ -> None
    
    let printTupleValues = function
        | ParseTuple vals ->
            let s =
                vals
                |> Array.map (fun a -> a.ToString())
                |> Array.reduce (fun a b -> sprintf "%s, %s" a b)
            printfn "(%s)" s
        | _ ->
            printf "not a tuple"
    
    printTupleValues ("hello world", 1)
    
  • 2

    我不知道您的功能是否已在当前的F#版本中重命名或删除 . 您应该在IDE的对象资源管理器中查看 FSharp.Reflection 来检查并查看this page .

相关问题