Пример. Обобщенная функция поиска минимального элемента в массиве. Элементы должны реализовывать интерфейс IComparable.

function MinElem(a: array of T): T;

where T: IComparable;

begin

var min: T := a[0];

forvar i := 1 to a.Length-1 do

if min.CompareTo(a[i])<0 then

min := a[i];

Result := max;

end;

К сожалению, нет возможности использовать операцию <, поскольку операции не входят в интерфейсы.

<p>Элементы функционального программирования</p><p>Лямбда-выражения</p>

Лямбда-выражение - это выражение специального вида, которое на этапе компиляции заменяется на имя подпрограммы, соответствующей лямбда-выражению и генерируемой компилятором на лету.

Здесь излагается полный синтаксис лямбда-выражений.

Здесь рассказывается о захвате лямбда-выражением переменных из внешнего контекста.

Лямбда-выражения запрещается использовать при инициализации полей класса или записи, внутри вложенных подпрограмм, в подпрограмме при наличии вложенной подпрограммы, в разделе инициализации модуля.

Синтаксис лямбда-выражений достаточно сложен и в данном пункте иллюстрируется на примерах.

Пример 1.

var f: integer -> integer := x -> x*x;

f(2);

Запись x -> x является лямбда-выражением, представляющем собой функцию с одним параметром x типа integer, возвращающую x*x типа integer. По данной записи компилятор генерирует следующий код:

function #fun1(x: integer): integer;

begin

Result := x*x;

end;

...

var f: integer -> integer := #fun1;

f(2);

Здесь #fun1 - это имя, генерируемое компилятором. Кроме того, код функции #fun1 также генерируется компилятором.

Пример 2. Фильтрация четных

Обычно лямбда-выражение передаётся как параметр подпрограммы. Например, в следующем коде

var a := Seq(3,2,4,8,5,5);

a.Where(x -> x mod 2 = 0).Print;

лямбда-выражение x -> x mod 2 = 0 задаёт условие отбора чётных чисел из массива a.

Пример 3. Сумма квадратов

var a := Seq(1,3,5);

writeln(a.Aggregate(0,(s,x)->s+x*x));

Иногда необходимо явно задавать тип параметров в лямбда-выражении.

Пример 4. Выбор перегруженной версии процедуры с параметром-лямбдой.

procedure p(f: integer -> integer);

begin

write(f(1));

end;

procedure p(f: real -> real);

begin

write(f(2.5));

end;

begin

p((x: real)->x*x);

end.

В данном примере вызов p(x -> x) вызовет ошибку компиляции, потому что компилятор не может выбрать, какую версию процедуры p выбирать. Задание типа параметра лямбды помогает устранить эту неоднозначность.

Пример 5. Лямбда-процедура.

procedure p(a: integer -> ());

begin

a(1)

end;

begin

p(procedure(x) -> write(x));

end.

<p>Захват переменных в лямбда-выражении</p>

Лямбда-выражение может использовать переменные из внешнего контекста. Такие переменные называются захваченными лямбда-выражением.

Пример 1. Захват переменной в запросе Select.

begin

var a := Seq(2,3,4);

var z := 1;

var q := a.Select(x->x+z);

q.Println;

z := 2;

q.Println;

end.

Здесь лямбда-выражение x->x+z захватывает внешнюю переменную z. Важно заметить, что при изменении значения переменной z запрос a.Select(x->x+z), хранящийся в переменной q, выполняется с новым значением z.

Пример 2. Накопление суммы во внешней переменной.

begin

var sum := 0;

var AddToSum: integer -> () := procedure (x) -> begin sum += x; end;

AddToSum(1);

AddToSum(3);

AddToSum(5);

writeln(sum);

end.

<p>Методы последовательностей</p>

Все последовательности имеют множество методов обработки последовательностей, реализованных как методы расширения.

Список методов последовательностей

* Методы Print

* Метод фильтрации Where

* Метод проецирования Select

* Метод проецирования SelectMany

* Методы Take, TakeWhile, Skip, SkipWhile

* Метод Sorted

* Методы OrderBy, OrderByDescending

* Методы ThenBy,ThenByDescending

* Метод ForEach

* Метод Concat

* Метод JoinIntoString

* Метод Zip

* Метод Distinct

* Методы Union,Intersect,Except

* Метод Reverse

* Метод SequenceEqual

* Методы First, FirstOrDefault

* Методы Last, LastOrDefault

* Методы Single, SingleOrDefault

* Метод DefaultIfEmpty

* Методы ElementAt, ElementAtOrDefault

* Методы Any, All

* Методы Count

* Метод Contains

* Метод Aggregate

* Методы Sum, Average

* Методы Min, Max

* Метод Join

* Метод GroupJoin

* Метод GroupBy

* Метод AsEnumerable

* Методы ToArray, ToList

* Метод ToDictionary

* Метод ToLookup

Перейти на страницу:

Похожие книги