Reputation: 4062
let print_type_c (x: Type)=
if x = typeof<Int32> then "int"
elif x = typeof<Single> then "float"
elif x = typeof<Tuple<_>> then "tuple"
elif x = typeof<FSharpFunc<Tuple<'inp>,'out>> then "function..."
else failwithf "Not supported(%A)" x
print_type_c (typeof<int>) // prints int
print_type_c (typeof<float32>) // prints float
print_type_c (typeof<int*int>) // throw an exception
I am trying to build a primitive F# quotations to Cuda compiler and I need to figure out how to translate tuple types to C struct types in function declarations, but I am really not familiar with how the .NET machinery works. It is disappointing that F# quotations do not return you a nice AST based on discriminated unions which would make everything explicit, but unless I want to do the typechecking myself, I'll have work with this.
What I am asking is - is there a way to the crappy piece of code above with pattern matching on .NET Type
s, because the above is clearly not working.
Edit: The question is not a duplicate because that linked question is asking how to print the properties of F# records, while I am asking how to print the types of native .NET types (including functions) inside F# quotations. A visual scan of the accepted answer here and there should show that they are completely different and not even using the same functions.
Upvotes: 2
Views: 105
Reputation: 80744
Runtime type inference? On types not known at compile time? No, sorry, doesn't exist, you'll have to build one yourself.
To check if a particular type is an instance of a specific generic type, you need to see if it's generic in the first place, and then get its generic definition, and compare that:
if x.IsGenericType && (x.GetGenericTypeDefinition() = typeof<System.Tuple<_>>.GetGenericTypeDefinition()) then "tuple" else "not"
Note that there is not just one Tuple
type, but many - Tuple<_>
, Tuple<_,_>
, Tuple<_,_,_>
, and so on - up to 8.
Same goes for FSharpFunc
:
if x.IsGenericType && (x.GetGenericTypeDefinition() = typeof<FSharpFunc<_,_>>.GetGenericTypeDefinition()) then "function" else "not"
To get generic arguments of a type, use .GetGenericArguments()
:
if x.IsGenericType && (x.GetGenericTypeDefinition() = typeof<FSharpFunc<_,_>>.GetGenericTypeDefinition())
then
sprintf "function %s -> %s" (x.GetGenericArguments().[0].Name) (x.GetGenericArguments().[1].Name)
else
"not function"
Upvotes: 2