5

C#では、式ツリーを使用してオブジェクトグラフの文字列表現をかなり簡単に作成できました。

public static string GetGraph<TModel, T>(TModel model, Expression<Func<TModel, T>> action) where TModel : class
{
            var method = action.Body as MethodCallExpression;
            var body = method != null ? method.Object != null ? method.Object as MemberExpression : method.Arguments.Any() ? method.Arguments.First() as MemberExpression : null : action.Body as MemberExpression;
            if (body != null)
            {
                string graph = GetObjectGraph(body, typeof(TModel))
                return graph;
            }
            throw new Exception("Could not create object graph");
}

F#では、同じことをしようとする見積もりを調べていましたが、それを完全に理解することはできません。PowerPackライブラリを使用して引用を式に変換しようとしましたが、これまでのところうまくいきませんでした。インターネット上の情報は、このトピックに関してかなりまばらに見えます。

入力が次の場合:

let result = getGraph myObject <@ myObject.MyProperty @>

出力は「myobject.MyProperty」である必要があります

4

2 に答える 2

5

fsiセッションで引用式から何が得られるかを確認できます。

> let v = "abc"
> <@ v.Length @>;;
val it : Expr<int>
= PropGet (Some (PropGet (None, System.String v, [])), Int32 Length, [])

> <@ "abc".Length @>;;
val it : Expr<int>
= PropGet (Some (Value ("abc")), Int32 Length, [])

qoutationsを解析するために利用できるすべてのアクティブなパターンの説明を見つけることができます

manual \ FSharp.Core \ Microsoft.FSharp.Quotations.Patterns.html

F#インストールディレクトリまたはmsdnサイト

「Quotations」という名前の章がある素敵なChrisSmithの本「ProgrammingF#」があります:)

したがって、結局のところ、単純なパーサーを書いてみてください。

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

let rec getGraph (expr: Expr) =
  let parse args =
    List.fold_left (fun acc v -> acc ^ (if acc.Length > 0 then "," else "") ^ getGraph v) "" args
  let descr s = function
    | Some v -> "(* instance " ^ s ^ "*) " ^ getGraph v
    | _ -> "(* static " ^ s ^ "*)"
  match expr with
  | Int32 i -> string i
  | String s -> sprintf "\"%s\"" s
  | Value (o,t) -> sprintf "%A" o
  | Call (e, methodInfo, av) ->
    sprintf "%s.%s(%s)" (descr "method" e) methodInfo.Name (parse av)
  | PropGet(e, methodInfo, av) ->
    sprintf "%s.%s(%s)" (descr "property" e) methodInfo.Name (parse av)
  | _ -> failwithf "I'm don't understand such expression's form yet: %A" expr

PSそしてもちろん、ASTを人間が読める形式に変換するためのコードが必要になります。

于 2009-12-19T10:01:39.670 に答える
4

この質問をしたときの状態がどのようなものであったかはわかりませんが、今日は次のようにPowerPackを使用してF#見積もりを式に変換できます。

<@ "asdf".Length @>.ToLinqExpression()

また、多くのF#引用符をF#の1行の非軽量構文コードに逆コンパイルできるライブラリUnquoteを開発しています。必要な入力/出力のような単純なインスタンスPropertyGet式を簡単に処理できます。

> decompile <@ "asdf".Length @>;;
val it : string = ""asdf".Length"

詳細については、同様の質問に対する私の回答を参照するか、Unquoteのホームページにアクセスしてください。

于 2011-02-27T23:31:45.953 に答える