Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从引用表达式匹配中获取模块、函数等的F#名称_F#_Quotations - Fatal编程技术网

如何从引用表达式匹配中获取模块、函数等的F#名称

如何从引用表达式匹配中获取模块、函数等的F#名称,f#,quotations,F#,Quotations,我继续为F#引号表达式的打印机工作,它不一定是完美的,但我想看看有什么可能。Microsoft.FSharp.Quotences.patterns和Microsoft.FSharp.Quotences.DerivedPatterns中用于分解引用表达式的活动模式通常会提供MemberInfo实例(如果适用),这些实例可用于获取属性、函数等的名称及其“声明”类型,例如模块或静态类。问题是,我只知道如何从这些实例中获取CompiledName,但我想要F#name。比如说, > <@ L

我继续为F#引号表达式的打印机工作,它不一定是完美的,但我想看看有什么可能。
Microsoft.FSharp.Quotences.patterns
Microsoft.FSharp.Quotences.DerivedPatterns
中用于分解引用表达式的活动模式通常会提供
MemberInfo
实例(如果适用),这些实例可用于获取属性、函数等的名称及其“声明”类型,例如模块或静态类。问题是,我只知道如何从这些实例中获取
CompiledName
,但我想要F#name。比如说,

> <@ List.mapi (fun i j -> i+j) [1;2;3] @> |> (function Call(_,mi,_) -> mi.DeclaringType.Name, mi.Name);;
val it : string * string = ("ListModule", "MapIndexed")
为此,您可以使用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检索函数名

编辑:

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);
正如pblasucci所暗示的,您可以使用
CompilationSourceName
属性来检索源名称:

let infos = mi.DeclaringType.GetMember(mi.Name)
let att = infos.[0].GetCustomAttributes(true)
let fName =
    (att.[1] :?> CompilationSourceNameAttribute).SourceName // fName is mapi 

我很确定您可以检查方法的自定义属性,以查看
CompilationSourceNameAttribute
;它的
SourceName
属性应该是您想要的。我会用一个合适的样本发布一个答案,但我现在不在开发计算机附近。谢谢分享!您也可以将其发布在Tomas的:D@StringerBell-我想您可能会感兴趣,我已经启动了一个开源项目Unquote(),它包含了一个报价打印机,我在这里更具体地讨论了它: