如何从引用的表达式匹配中获取模块、函数等的 F# 名称
我继续致力于开发 F# 引用表达式的打印机,它不一定是完美的,但我想看看有什么可能。用于分解引用表达式的 Microsoft.FSharp.Quotations.Patterns
和 Microsoft.FSharp.Quotations.DerivedPatterns
中的活动模式通常会提供 MemberInfo
实例在适当的时候,它们可用于获取属性、函数等的名称及其“声明”类型,例如模块或静态类。问题是,我只知道如何从这些实例中获取 CompiledName,但我想要 F# 名称。例如,
> <@ 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")
?是否可以?
仅供参考,这是我在 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);
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")
How can this match be rewritten to return ("List", "mapi")
? Is it possible?
FYI, here is my final polished solution from Stringer Bell and pblasucci's help:
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);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用 F# powerpack 来实现此目的:
但是,我不认为是否可以使用 powerpack 检索函数名称。
编辑:
正如 pblasucci 所暗示的,您可以使用
CompilationSourceName
属性来检索源名称:You can use F# powerpack for that purpose:
However, I don't think if it's possible to retrieve function name with powerpack.
Edit:
As hinted by pblasucci, you can use
CompilationSourceName
attribute for retrieving source name: