Реализовал сопоставление с образцом для полиморфных классов.
Теперь с помощью оператора match можно распознавать полиморфные типы.
Примеры использования здесь:
match-on-polymorphic-class.n.
Общая идея такова. Если мы имеем иерархия классов где некоторые поля могут содержать полиморфные значения.
Например:
[Record]
class A
{
public Field1 : int;
public Field2 : A; // Поле может содержать полиморфное значение!
public override ToString() : string { $<#A($Field1, '$Field2')#> }
}
[Record]
class B : A
{
public Field3 : string;
public override ToString() : string { $<#B($Field1, '$Field2', "$Field3")#> }
}
То мы можем распознавать некоторые паттерны полагясь на то, что поля могут содержать и подтипы того типа, что задан для поля:
def test2 (a : A)
{
| (1, B where (Field1 = 1)) => WriteLine($"1 $a");
| (1, A where (Field1 = 1) as x) => WriteLine($"2 x=$x");
| (1, B where (Field3 = "test") as x) as y => WriteLine($"3 x=$x y=$y");
| _ => WriteLine("fail");
}
test2(A(1, B(1, null, "test")));
test2(A(1, A(1, null)));
test2(B(1, A(1, null), "test"));
test2(A(1, B(2, null, "test")));
Прошу заметить, что для сопоставления с образцом классов, оные не обязаны быть помечены мета-атрибутом [Record] или иметь публичных конструторов. Паттерн типа: "Тип where (Поле = паттарн, Свойство = паттерн)" работают на любых классах.