Как имитировать проверку типа компилятора F #? - PullRequest
4 голосов
/ 16 июня 2019

В 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, какие функции можно вызвать для имитации проверки типов, выполняемой компилятором?

Ответы [ 2 ]

6 голосов
/ 16 июня 2019

Причина, по которой GetType конкретной лямбда-функции отличается от typeof<int -> int>, заключается в том, что компилятор F # генерирует новый класс для функции, которая наследуется от int -> int. Другими словами, типы не совпадают, но тип, который вы получаете через GetType, наследуется от int -> int.

Вы можете легко проверить это, используя IsAssignableFrom. true:

typeof<int -> int>.IsAssignableFrom((fun x -> x*x).GetType())
3 голосов
/ 16 июня 2019

Вы можете использовать оператор :? для проверки по типу. Я поместил его в коробку, потому что (int -> int) это запечатанный тип.

F # Почему я не могу использовать:? оператор в F # интерактивный?

> let f = box (fun x -> x*x);;
val f : obj
> f :? (int -> int);;
val it : bool = true

Если вы хотите создать свою функцию проверки типов, вы можете использовать это. «Т и вещь типа Т», они всегда будут иметь один и тот же тип, поэтому я сделал здесь объект х, и вы можете пометить его, прежде чем смотреть на него. Однако вам, вероятно, не нужно этого делать, поэтому, если вы новичок в 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 :)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...