我继续为 F# 引用表达式开发打印机,它不一定是完美的,但我想看看有什么可能。用于分解引用表达式的活动模式通常会在适当时提供Microsoft.FSharp.Quotations.Patterns
实例,这些可用于获取属性、函数等的名称及其“声明”类型,例如模块或静态类。问题是,我只知道如何从这些实例中获取,但我想要 F# 名称。例如,Microsoft.FSharp.Quotations.DerivedPatterns
MemberInfo
CompiledName
> <@ List.mapi (fun i j -> i+j) [1;2;3] @> |> (function Call(_,mi,_) -> mi.DeclaringType.Name, mi.Name);;
val it : string * string = ("ListModule", "MapIndexed")
如何将这个匹配重写为 return ("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);