Основы функционального программирования/Структуры данных и базисные операции — 2: различия между версиями

Содержимое удалено Содержимое добавлено
Начало основательной правки...
→‎Типы в функциональных языках: Продолжение основательной правки
Строка 19:
'''Пример 8. Тип функции <math>add(x, y)</math>.'''
 
Предположительно, каждый из аргументов функции <math>add</math> уже означен, пусть <math>x = 5</math>, <math>y = 7</math>. В этом случае из функции <math>add</math> путемпутём удаления первого аргумента получается новая функция — <math>add5</math>, которая прибавляет к своему единственному аргументу число <math>5</math>. ЕеЕё тип получается легко, он по определению таков: Real<math>Float \rightarrow RealFloat</math>. Теперь, возвращаясь назад, можно понять, почему тип функции <math>add</math> равен Real<math>Float \rightarrow (RealFloat \rightarrow RealFloat)</math>.
 
Для того чтобы не изощряться с написанием функций типа <math>add5</math> (как в предыдущем примере), была придумана специальная аппликативная форма записи в виде «оператор-операнд». Предпосылкой для этого послужило новое видение на функции в функциональном программировании. Ведь если традиционно считалось, что выражение <math>f (5)</math> обозначает «применение функции <math>f</math> к значению аргумента, равному <math>5</math>» (т.&nbsp;е. вычисляется только аргумент), то в функциональном программировании считается, что значение функции также вычисляется. Так, возвращаясь к примеру &nbsp;8, функцию <math>add</math> можно записать как <math>(add (x)) y</math>, а когда аргументы получают конкретные значения (например, <math>(add (5)) 7)</math>, сначала вычисляются все функции, пока не появится функция одного аргумента, которая применяется к последнему.
 
Таким образом, если функция <math>f</math> имеет тип A1<math>A_{1} \rightarrow (A2A_{2} \rightarrow ( ... \ldots(AnA_{n} \rightarrow B) ... \ldots))</math>, то чтобы полностью вычислить значение <math>f (a1a_{1}, a2a_{2}, ...\ldots, ana_{n})</math> необходимо последовательно провести вычисление <math>( ... \ldots(f (a1a_{1}) a2a_{2}) ... \ldots) ana_{n}</math>. И результатом вычисления будет объект типа <math>B</math>.
 
Соответственно выражение, в котором все функции рассматриваются как функции одного аргумента, а единственной операцией является аппликация (применение), называются выражениями в форме «оператор-операнд». Такие функции получили название «каррированные», а сам процесс сведения типа функции к виду, приведенному в предыдущем абзаце — каррированием (по имени Карри Хаскелла).
 
Если вспомнить λ-исчисление, то обнаружится, что в немнём уже есть математическая абстракция для аппликативных форм записей. Например:
 
<center><math>f (x) = x^{2} + 5 \Rightarrow \lambda x.(x^{2} + 5)</math></center>
<center>
 
<math>f (x) = x^{2} + 5 \Rightarrow \lambda x.(x^{2} + 5)</math>
<center><math>f (x, y) = x + y \Rightarrow \lambda y.\lambda x.(x + y)</math></center>
 
<center><math>f (x, y, z) = x^{2} + y^{2} + z^{2} \Rightarrow \lambda z.\lambda y.\lambda x.(x^{2} + y^{2} + z^{2})</math></center>
</center>
 
И так далее...