如何模仿F#编译器类型检查?

时间:2019-06-16 19:14:12

标签: f#

在F#中,我可以编写一个函数(fun x -> x * x)并确认其类型为int->int,因为以下代码可以编译:

let typeCheck<'T> (x:'T) = ()
typeCheck<int->int> (fun x -> x*x)

另一方面,此功能的GetTypetypeof<int->int>不同:

> (fun x -> x*x).GetType() = typeof<int -> int>
val it : bool = false

如果不是GetType()typeof,我可以调用哪些函数来模仿编译器进行的类型检查?

2 个答案:

答案 0 :(得分:6)

特定lambda函数的GetTypetypeof<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 :)