Сопоставление с образцом для полиморфных классов
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.09.09 01:21
Оценка: 14 (3)
Реализовал сопоставление с образцом для полиморфных классов.

Теперь с помощью оператора 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 (Поле = паттарн, Свойство = паттерн)" работают на любых классах.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.