Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# - Get list of methods in module

Tags:

f#

I have module like this

module CommonModule

    let addFive x =
        x+5

    let multiFive x =
        x*5

And I would like to list methods of this module by reflection. I found this: Can you list the contents of a namespace or module in F#, but I don't know how to use it. I'm new in F#. Please help

like image 347
lukaszb Avatar asked Jun 12 '18 12:06

lukaszb


1 Answers

I think the only way to do this is to declare a type inside the module, then use reflection to get the DeclaringType and call GetMethods on that:

open System.Reflection

module CommonModule =
    type Marker = interface end

    let f x = x * x

typeof<CommonModule.Marker>.DeclaringType.GetMethods()

This will give you a MethodInfo [] containing f and the methods inherited from System.Object:

[|Int32 f(Int32); System.String ToString(); Boolean Equals(System.Object);
Int32 GetHashCode(); System.Type GetType()|]

EDIT (responding to lukaszb's comment)

If you want to look up the module by name, you'll need to get the assembly first, then find the module type within the assembly and call GetMethods. To do this for the previous example, you would add the following code:

// Get the assembly somehow (by name, by GetEntryAssembly, etc)
let assembly = Assembly.GetExecutingAssembly()

// Retrieve the methods (including F# functions) on the module type
let functions =
    match assembly.GetTypes() |> Array.tryFind (fun t -> t.Name = "CommonModule") with
    | Some moduleType -> moduleType.GetMethods()
    | None -> [||]

// Find the function you want
match functions |> Array.tryFind (fun f -> f.Name = "f") with
| Some f -> f.Invoke(null, [|2|]) // Invoke the function
| None -> failwith "Function `f` not found"

One benefit of doing it this way is that you no longer need the Marker type in the module.

like image 144
Aaron M. Eshbach Avatar answered Oct 24 '22 05:10

Aaron M. Eshbach