In F#, I can write a function (fun x -> x * x)
and confirm it has type int->int
because the following code compiles:
let typeCheck<'T> (x:'T) = ()
typeCheck<int->int> (fun x -> x*x)
On the other hand, GetType
for this function doesn't agree with typeof<int->int>
:
> (fun x -> x*x).GetType() = typeof<int -> int>
val it : bool = false
If not GetType()
and typeof
, what functions can I call to mimic the type-checking done by the compiler?
The reason why GetType
of a specific lambda function is not the same as typeof<int -> int>
is that the F# compiler generates a new class for the function which inherits from int -> int
. In other words, the types are not the same, but the type you get via GetType
inherits from int -> int
.
You can check for this easily using IsAssignableFrom
. The following is true
:
typeof<int -> int>.IsAssignableFrom((fun x -> x*x).GetType())
You can use the :?
operator to check based on type. I boxed it because (int -> int)
is a sealed type.
F# Why can't I use the :? operator in F# interactive?
> let f = box (fun x -> x*x);;
val f : obj
> f :? (int -> int);;
val it : bool = true
If you wanted to build your typecheck function you could use this. A 'T and a thing of type 'T, they would always have the same type so I made x an object here, and you can box it before looking at it. However you probably don't need to do this, so if you're new to F# you may be working harder than you need to.
let typeCheck<'T> (x: obj) =
x :? 'T
//which is the same as
x :? (int -> int)
//so you probably don't need to define your own :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With