5

私はF#で引用された式のプ​​リンターで作業を続けています。完璧である必要はありませんが、何が可能かを見たいと思います。引用符で囲まれた式を分解するためMicrosoft.FSharp.Quotations.Patternsに使用されるアクティブなパターンは、通常、適切な場合にインスタンスを提供します。これらは、プロパティ、関数などの名前と、モジュールや静的クラスなどの「宣言」タイプを取得するために使用できます。問題は、これらのインスタンスからを取得する方法しか知らないのですが、F#の名前が欲しいのです。例えば、Microsoft.FSharp.Quotations.DerivedPatternsMemberInfoCompiledName

> <@ List.mapi (fun i j -> i+j) [1;2;3] @> |> (function Call(_,mi,_) -> mi.DeclaringType.Name, mi.Name);;
val it : string * string = ("ListModule", "MapIndexed")

この一致をどのように書き直して返すことができ("List", "mapi")ますか?出来ますか?

参考までに、これがStringerBellとpblasucciの助けによる私の最終的な洗練されたソリューションです。

let moduleSourceName (declaringType:Type) =
    FSharpEntity.FromType(declaringType).DisplayName

let methodSourceName (mi:MemberInfo) =
    mi.GetCustomAttributes(true)
    |> Array.tryPick 
            (function
                | :? CompilationSourceNameAttribute as csna -> Some(csna)
                | _ -> None)
    |> (function | Some(csna) -> csna.SourceName | None -> mi.Name)

//usage:
let sourceNames =
    <@ List.mapi (fun i j -> i+j) [1;2;3] @> 
    |> (function Call(_,mi,_) -> mi.DeclaringType |> moduleSourceName, mi |> methodSourceName);
4

1 に答える 1

4

その目的でF#powerpackを使用できます。

open Microsoft.FSharp.Metadata
...
| Call(_, mi, _) ->
    let ty = Microsoft.FSharp.Metadata.FSharpEntity.FromType(mi.DeclaringType)
    let name = ty.DisplayName // name is List

ただし、powerpackで関数名を取得できるかどうかはわかりません。

編集:

pblasucciが示唆するように、CompilationSourceNameソース名を取得するために属性を使用できます。

let infos = mi.DeclaringType.GetMember(mi.Name)
let att = infos.[0].GetCustomAttributes(true)
let fName =
    (att.[1] :?> CompilationSourceNameAttribute).SourceName // fName is mapi 
于 2011-01-05T13:57:07.363 に答える