如何对本机 .NET 类型进行模式匹配?
How to do the equivalent of pattern matching on native .NET types?
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
我正在尝试为 Cuda 编译器构建原始 F# 引用,我需要弄清楚如何在函数声明中将元组类型转换为 C 结构类型,但我真的不熟悉 .NET 机制的工作原理。令人失望的是,F# 引语没有 return 你是一个基于可区分联合的好 AST,它会使所有内容都明确,但除非我想自己进行类型检查,否则我将使用它。
我想问的是 - 有没有办法在 .NET Type
s 上使用模式匹配来处理上面那段蹩脚的代码,因为上面的代码显然不起作用。
编辑:这个问题不是重复的,因为那个链接的问题是问如何打印 F# 记录的属性,而我问的是如何在 F# 引号内打印本机 .NET 类型(包括函数)的类型。在这里和那里接受的答案的视觉扫描应该表明它们是完全不同的,甚至没有使用相同的功能。
运行时类型推断?关于编译时未知的类型?不,抱歉,不存在,您必须自己构建一个。
要检查特定类型是否是特定泛型类型的实例,您需要首先查看它是否是泛型,然后获取其泛型定义,并进行比较:
if x.IsGenericType && (x.GetGenericTypeDefinition() = typeof<System.Tuple<_>>.GetGenericTypeDefinition()) then "tuple" else "not"
请注意,不仅有一种 Tuple
类型,还有多种类型 - Tuple<_>
、Tuple<_,_>
、Tuple<_,_,_>
等等 - 最多 8 种。
FSharpFunc
也是如此:
if x.IsGenericType && (x.GetGenericTypeDefinition() = typeof<FSharpFunc<_,_>>.GetGenericTypeDefinition()) then "function" else "not"
要获取类型的泛型参数,请使用 .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"
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
我正在尝试为 Cuda 编译器构建原始 F# 引用,我需要弄清楚如何在函数声明中将元组类型转换为 C 结构类型,但我真的不熟悉 .NET 机制的工作原理。令人失望的是,F# 引语没有 return 你是一个基于可区分联合的好 AST,它会使所有内容都明确,但除非我想自己进行类型检查,否则我将使用它。
我想问的是 - 有没有办法在 .NET Type
s 上使用模式匹配来处理上面那段蹩脚的代码,因为上面的代码显然不起作用。
编辑:这个问题不是重复的,因为那个链接的问题是问如何打印 F# 记录的属性,而我问的是如何在 F# 引号内打印本机 .NET 类型(包括函数)的类型。在这里和那里接受的答案的视觉扫描应该表明它们是完全不同的,甚至没有使用相同的功能。
运行时类型推断?关于编译时未知的类型?不,抱歉,不存在,您必须自己构建一个。
要检查特定类型是否是特定泛型类型的实例,您需要首先查看它是否是泛型,然后获取其泛型定义,并进行比较:
if x.IsGenericType && (x.GetGenericTypeDefinition() = typeof<System.Tuple<_>>.GetGenericTypeDefinition()) then "tuple" else "not"
请注意,不仅有一种 Tuple
类型,还有多种类型 - Tuple<_>
、Tuple<_,_>
、Tuple<_,_,_>
等等 - 最多 8 种。
FSharpFunc
也是如此:
if x.IsGenericType && (x.GetGenericTypeDefinition() = typeof<FSharpFunc<_,_>>.GetGenericTypeDefinition()) then "function" else "not"
要获取类型的泛型参数,请使用 .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"