Pattern Matching в PascalABC.NET


#1

Pattern Matching - это больше прерогатива функциональных языков программирования. Опять-таки, Pattern Matching есть в Haskell.

В последнее время Pattern Matching проникает и в языки вроде C#:

Pattern Matching напоминает расширенный case по типам.

Вот пример для начала:

type
  Line = class
  end;
  Rectangle = auto class
    X,Y,Width,Height: real;
  end;
  Circle = auto class
    X,Y,Radius: real;
  end;
  
begin
  var l := new List<Object>;
  l.Add(new Line);
  l.Add(new Circle(10,10,5));
  l.Add(new Rectangle(10,10,20,10));
  foreach var x in l do
    match x with
  Line(var ll): Println('Line S =',0);
  Circle(var c): Println('Circle S =',c.Radius*c.Radius*Pi);
  Rectangle(var r): Println('Rectangle S =',r.Width*r.Height);
    end;
end.  

Здесь в полиморфном списке вычисляются площади фигур. Переменная x в зависимости от динамического типа деконструируется в переменную соответствующего типа (Line, Circle или Rectangle). И затем находится площадь.


#2

Однако, вкусняшка!


#3

Оказывается, ещё можно делать так:

begin
  match new object with
    integer(i) when i > 5: ;
  end;
end.

#4

И так:

 type
   Person = auto class
    
     name: string;
     age: integer;
     
     procedure Deconstruct(var name: string; var age: integer);
     begin
       name := self.name;
       age := self.age;
     end;
     
   end;

begin
  var p := new Person('Петр', 25);
  if p is Person(var name, var age) then
    Println(name, age);
end. 

#5

Кстати, @Admin это нормально что между var name и var age можно ставить и запятую и точку с запятой?


#6

Можно, пока я отвечу? Это совершенно нормально. Синтаксис языка Паскаль требует отделять формальные параметры в списке заголовка подпрограммы запятой, либо точкой с запятой. Запятая разделяет параметры, имеющие один тип и способ вызова. Если тип и/или способ вызова разный, требуется разделитель “точка с запятой”. При этом синтаксис не запрещает и каждый параметр отделять точкой с запятой - может быть, так программисту больше нравится)).


#7
procedure p1(a,b:byte) := exit;

begin
  p1(0;0);//Ошибка: Встречено ';', а ожидалось ')'
end.

#8

Я писал, если Вы обратите внимание, о

А Вы использовали при вызове в фактических.

Это ведь именно описание. Как в любом блоке. Сравните:

begin
  var a: integer;
  var b: integer
end.

и

begin
  var a, b: integer;
end.

Допустимы оба способа описания. Так и в подпрограммах.


#9

Нормально. Можно даже var не ставить. Воспринимайте это как одну или несколько секций формальных параметров. Конечно полной аналогии нет, поэтому тут просто проектное решение, интуитивно нормальное.

Кстати в автоклассе деконструктор генерируется по полям ровно такой. Так что его можно не писать