tesla1060
tesla1060

Reputation: 2765

f# type as function input parameter?

can type be used as a function input parameter?

open System 
open Microsoft.FSharp.Reflection 

type MyTuple = DateTime*int*decimal*decimal 

let f tupleType = 
    let ret = FSharpValue.MakeTuple([|DateTime.Now;1;1.0M;1.0M|],typeof<tupleType>) 
    let myTuple = ret :?> MyTuple 
0 

[<EntryPoint>] 
let main argv = 
    f MyTuple 
    0

in this case I get the the type tupleType is not defined .

Upvotes: 1

Views: 225

Answers (2)

CaringDev
CaringDev

Reputation: 8551

For casting you need static (compile time) information. A normal parameter is runtime information. It's easy to go static -> runtime but impossible the other way around. So:

open System
open Microsoft.FSharp.Reflection

type MyTuple = DateTime*int*decimal*decimal

let f<'a> =
    let ret = FSharpValue.MakeTuple([|DateTime(2042, 3, 1, 4, 1, 2); 1; 1.0M; 1.0M|], typeof<'a>)
    ret :?> 'a

[<EntryPoint>]
let main _ =
    // All these print "(01.03.2042 04:01:02, 1, 1.0M, 1.0M)"
    let mt = f<MyTuple>
    printfn "%A" mt

    let dt, i, d1, d2 = f<MyTuple>
    printfn "%A" (dt, i, d1, d2)

    let mt : MyTuple = f
    printfn "%A" mt

    // Except this one (obviously)
    try
        let mt = f<string>
        printfn "%A" mt
    with
    | :? ArgumentException ->
        printfn "Runtime madness"
    0

Upvotes: 1

John Palmer
John Palmer

Reputation: 25516

So the arguments to functions are objects, not types so this can't work.

What you are trying to do here is not particularly easy. Typically, when you are using reflection your approach is flawed.

You could do something where the argument became f typeof<whatever> or something similar, but it probably won't solve your original problem.

Upvotes: 3

Related Questions