Мой вопрос касается следующей программы.
open System
// Types
type Car (brand: string) =
member _.Brand = brand
type BMW () =
inherit Car "BMW"
type Pet =
| Cat
| Dog
[<EntryPoint>]
let main argv =
// Match subtype of test-expression type: ok
let car = Car "Mercedes"
let carResult =
match car with
| :? BMW -> 1
| _ -> 0
// Match type of test-expression: "will always hold" warning
let bmw = BMW ()
let bmwResult =
match bmw with
| :? BMW -> 1
| _ -> 0
// Catch any exception: "will always hold" warning
let exceptionResult =
try
1/0
with
| :? Exception -> 2
// Match type of test-expression (union type): "The type 'Pet' does not have any proper subtypes" error
let cat = Cat // this has type Pet
let catResult =
match cat with
| :? Pet -> 1
| _ -> 0
0
В первом тесте тестовое выражение имеет тип Car
, подтипом которого является тип в тестовом шаблоне типа BMW
, и нет никаких предупреждений или ошибок. Во втором и третьем тестах тип шаблона проверки типа совпадает с типом тестового выражения, и понятно, что выдается предупреждение, потому что, когда программист проверяет, действительно ли BMW
является BMW
или Exception
на самом деле Exception
, скорее всего, это логическая ошибка.
Последний тест имеет ту же форму, что и тесты два и три: выражение-тест имеет тип Pet
, а шаблон теста типа также имеет тип Pet
. Так почему же в этом случае выдает ошибку? Ошибка говорит The type 'Pet' does not have any proper subtypes...
. Но BMW
не имеет подтипов и не выдает этой ошибки. Кроме того, страница Pattern Matching (в разделе «Шаблон проверки типа») говорит, что «Если тип ввода соответствует (или производному типу) типу, указанному в шаблоне, совпадение завершается успешно». Pet
соответствует Pet
, следовательно, и т. д. Почему тип объединения обрабатывается по-разному?