如何从引用的表达式匹配中获取模块,函数等的F#名称 [英] How to Get the F# Name of a Module, Function, etc. From Quoted Expression Match

查看:106
本文介绍了如何从引用的表达式匹配中获取模块,函数等的F#名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我继续在打印机上使用F#引用的表达式,它不一定是完美的,但是我想知道有什么可能. Microsoft.FSharp.Quotations.PatternsMicrosoft.FSharp.Quotations.DerivedPatterns中用于分解带引号的表达式的活动模式通常会在适当的时候提供MemberInfo实例,这些实例可用于获取属性,函数等的名称及其声明"类型,例如作为模块或静态类.问题是,我只知道如何从这些实例中获取CompiledName,但我想使用F#名称.例如,

I continue to work on a printer for F# quoted expressions, it doesn't have to be perfect, but I'd like to see what is possible. The active patterns in Microsoft.FSharp.Quotations.Patterns and Microsoft.FSharp.Quotations.DerivedPatterns used for decomposing quoted expressions will typically provide MemberInfo instances when appropriate, these can be used to obtain the name of a property, function, etc. and their "declaring" type, such as a module or static class. The problem is, I only know how to obtain the CompiledName from these instances but I'd like the F# name. For example,

> <@ 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")?有可能吗?

How can this match be rewritten to return ("List", "mapi")? Is it possible?

仅供参考,这是我在Stringer Bell和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);

推荐答案

您可以为此使用F#powerpack:

You can use F# powerpack for that purpose:

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

但是,我认为是否可以通过powerpack检索函数名称.

However, I don't think if it's possible to retrieve function name with powerpack.

如pblasucci所暗示,您可以使用CompilationSourceName属性来检索源名称:

As hinted by pblasucci, you can use CompilationSourceName attribute for retrieving source name:

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

这篇关于如何从引用的表达式匹配中获取模块,函数等的F#名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆