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# 如何获取[<;ReflectedDefinition>;]标记模块中函数的AST?_F# - Fatal编程技术网

F# 如何获取[<;ReflectedDefinition>;]标记模块中函数的AST?

F# 如何获取[<;ReflectedDefinition>;]标记模块中函数的AST?,f#,F#,问题在于实际获取模块的类型。为了做到这一点,菲利普·特里福德给出了一个很好的答案: 基本上,向模块添加一个helper值,该值返回该模块的类型: open Microsoft.FSharp.Quotations open Microsoft.FSharp.Quotations.DerivedPatterns open Microsoft.FSharp.Reflection open System.Reflection 然后,我可以打印结果,例如: [|“get_fooType:Some Pro

问题在于实际获取模块的类型。为了做到这一点,菲利普·特里福德给出了一个很好的答案:

基本上,向模块添加一个helper值,该值返回该模块的类型:

open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.DerivedPatterns
open Microsoft.FSharp.Reflection
open System.Reflection
然后,我可以打印结果,例如:

[|“get_fooType:Some PropertyGet(Some(Call(None,TypeOf,[])),DeclaringType,[])”; “get_x:Some Value(5)”; y:一些Lambda(unitVar0,值(6)); “z:一些Lambda(a,a)”|]


对于用例,当反射的定义位于另一个程序集中(例如F#dll)时,可以不使用标记接口技巧,如下所示:

 let foo_members = 
     Foo.fooType.GetMethods()
     |> Array.filter (fun mi -> match mi with | MethodWithReflectedDefinition x -> true | _ -> false)
     |> Array.map (fun m -> sprintf "%s: %A" (m.Name) (Expr.TryGetReflectedDefinition(m :> MethodBase) ) )
开放系统
打开Microsoft.FSharp.quotes
打开Microsoft.FSharp.Quotences.DerivedPatterns
打开Microsoft.FSharp.Reflection
开放系统。反射
打开FSharp.Reflection.FSharpReflectionExtensions
让tryGetReflectedModules(a:组件):seq=
a、 定义类型
|>顺序过滤器
(乐趣dt->
自定义属性
|>Seq.map(有趣的cad->cad.AttributeType)
|>Seq.filter((=)(typeof))
|>我是空的
|>不是
)
让astFromReflectedDefinition(mi:MethodInfo):Expr选项=
mi:>MethodBase |>Expr.TryGetReflectedDefinition
让reflectedMethodsOfAModule(m:System.Type):(MethodInfo*Expr)[]=
m、 GetMethods()
|>Array.map(乐趣m->(m,astFromReflectedDefinition m))
|>Array.filter(snd>>Option.isSome)
|>Array.map(fun(x,y)->(x,Option.get y))
let reflectAssembly(assemblyPath:string)=
设a=System.Reflection.Assembly.LoadFile(assemblyPath)
A.
|>TRYGETREFLECTED模块
|>Seq.map(fun x->(x,reflectedMethodsOfAModule(x.AsType()))
其中,例如,我用于测试上述代码的程序集如下所示:

open System
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.DerivedPatterns
open Microsoft.FSharp.Reflection
open System.Reflection
open FSharp.Reflection.FSharpReflectionExtensions

let tryGetReflectedModules (a : Assembly) : seq<TypeInfo>  = 
    a.DefinedTypes 
    |> Seq.filter 
        (fun dt -> 
            dt.CustomAttributes
            |> Seq.map (fun cad -> cad.AttributeType)
            |> Seq.filter ((=) (typeof<ReflectedDefinitionAttribute>))
            |> Seq.isEmpty
            |> not
        )

let astFromReflectedDefinition (mi : MethodInfo) : Expr option =
    mi :> MethodBase |> Expr.TryGetReflectedDefinition

let reflectedMethodsOfAModule (m : System.Type) : (MethodInfo * Expr) [] =
    m.GetMethods()
    |> Array.map (fun m -> (m,astFromReflectedDefinition m))
    |> Array.filter (snd >> Option.isSome)
    |> Array.map (fun (x,y) -> (x, Option.get y))

let reflectAssembly (assemblyPath : string) =
    let a = System.Reflection.Assembly.LoadFile(assemblyPath) 
    a 
    |> tryGetReflectedModules
    |> Seq.map (fun x -> (x,reflectedMethodsOfAModule (x.AsType())))
名称空间输入
[]
模块Api=
让跟踪s=
对于[0..3]中的uu,执行System.Diagnostics.Trace.WriteLine s
[]
模块Foo=
让foobar(x:string):string=
x、 托珀()

您可以在程序集中获得顶级类型,它们恰好是(静态)类,表示Fsharp程序集的模块,并测试
ReflectedDefinitionAttribute
的存在。然后,你从那里开始。

我看到了这个问题。我使用
GetModuleType
helper函数尝试了这个答案。我尝试了交互式,但没有成功。我认为你的答案大致相同。有没有一种方法不使用powerpack(现在应该已经过时了)并且在interactive中也可以使用?还有,哪一个在不向模块添加标签或类似内容的情况下工作?我记得我在其他论坛上问过这件事,但一直没有得到答案。为什么没有类似的
Microsoft.FSharp.Reflection.Module.GetType()
呢?@BitTickler这只是这个问题的第一个答案,需要powerpack。我在那里发布的示例代码在interactive中工作得很好。事实上-只是复制了一下,它就工作了!好吧,我将把它作为一个解决办法,直到一些微软的家伙决定应该有一个简单的方法来做到这一点!谢谢你@BitTickler我快速浏览了F#语言设计用户语音网站,似乎之前没有提到过,是否值得在那里列出?我在思考如何对需要不同语言协作的应用程序进行(元)编程时偶然发现了这一点。示例:SecondLife脚本语言和http,以及一些SecondLife基于AJAX的HUD的脚本。或者:一些websocket html应用程序的f#后端。更为深奥的是:在F#中编程C,在F#中测试它,然后从中生成代码,希望有更少的bug。每当我想到这些事情,我都会偶然发现如何在模块上使用[]的问题。角落案例还是对公众有用?你决定;)
[<ReflectedDefinition>]
module Foo = 
    type internal IMarker = interface end
    let fooType = typeof<IMarker>.DeclaringType

    let x = 5
    let y () = 6
    let z a = a
 let foo_members = 
     Foo.fooType.GetMethods()
     |> Array.filter (fun mi -> match mi with | MethodWithReflectedDefinition x -> true | _ -> false)
     |> Array.map (fun m -> sprintf "%s: %A" (m.Name) (Expr.TryGetReflectedDefinition(m :> MethodBase) ) )
open System
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.DerivedPatterns
open Microsoft.FSharp.Reflection
open System.Reflection
open FSharp.Reflection.FSharpReflectionExtensions

let tryGetReflectedModules (a : Assembly) : seq<TypeInfo>  = 
    a.DefinedTypes 
    |> Seq.filter 
        (fun dt -> 
            dt.CustomAttributes
            |> Seq.map (fun cad -> cad.AttributeType)
            |> Seq.filter ((=) (typeof<ReflectedDefinitionAttribute>))
            |> Seq.isEmpty
            |> not
        )

let astFromReflectedDefinition (mi : MethodInfo) : Expr option =
    mi :> MethodBase |> Expr.TryGetReflectedDefinition

let reflectedMethodsOfAModule (m : System.Type) : (MethodInfo * Expr) [] =
    m.GetMethods()
    |> Array.map (fun m -> (m,astFromReflectedDefinition m))
    |> Array.filter (snd >> Option.isSome)
    |> Array.map (fun (x,y) -> (x, Option.get y))

let reflectAssembly (assemblyPath : string) =
    let a = System.Reflection.Assembly.LoadFile(assemblyPath) 
    a 
    |> tryGetReflectedModules
    |> Seq.map (fun x -> (x,reflectedMethodsOfAModule (x.AsType())))
namespace Input

[<ReflectedDefinition>]
module Api =
    let trace s = 
        for _ in [0..3] do System.Diagnostics.Trace.WriteLine s

[<ReflectedDefinition>]
module Foo =
    let foobar (x : string) : string =
        x.ToUpper()