在F#中,我可以编写一个函数(fun x -> x * x)
并确认其类型为int->int
,因为以下代码可以编译:
let typeCheck<'T> (x:'T) = ()
typeCheck<int->int> (fun x -> x*x)
另一方面,此功能的GetType
与typeof<int->int>
不同:
> (fun x -> x*x).GetType() = typeof<int -> int>
val it : bool = false
如果不是GetType()
和typeof
,我可以调用哪些函数来模仿编译器进行的类型检查?
答案 0 :(得分:6)
特定lambda函数的GetType
与typeof<int -> int>
不同的原因是F#编译器为该函数生成了一个新类,该类继承自int -> int
。换句话说,类型不同,但是您通过GetType
获得的类型继承自int -> int
。
您可以使用IsAssignableFrom
轻松地进行检查。以下是true
:
typeof<int -> int>.IsAssignableFrom((fun x -> x*x).GetType())
答案 1 :(得分:3)
您可以使用:?
运算符根据类型进行检查。我将其装箱,因为(int -> int)
是密封类型。
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
如果要构建类型检查功能,可以使用此功能。 'T和类型'T的事物,它们总是具有相同的类型,因此我在这里将x设为对象,可以在查看之前将其装箱。但是,您可能不需要执行此操作,因此,如果您不熟悉F#,则可能会比需要的工作还要努力。
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 :)