Конспекти лекцій «Haskell як перша мова програмування»

Привіт Habr! Сьогодні ми поговоримо про поліморфізм функцій, операторів і каринг. Нагадую, що лекції розраховані на новачків, а конспект передбачає стислу форму викладу. Якщо все ще цікаво…

Поліморфізм

Функція поліморфна, якщо вона здатна оперувати різними типами даних. Найпростіша поліморфна функція - функція тотожності:

Найчастіше поліморфізм використовують для роботи зі списками (воно і зрозуміло):

Область визначення цієї функції (що обчислює, очевидно, довжину списку) є список змінних типу a. Таку конструкцію просто називають просто: «список ашок». Функція прийме будь-який список на вхід. Більшість функцій у прелюдії є поліморфними. Не полінуйтеся - загляньте. А, поки що, ось ще приклад:

Функція filter залишає у списку лише елементи, що задовольняють певній умові.

Як бачите, поліморфний тип може бути областю значення функції:

У цьому випадку функція error приймає на вхід рядок про помилку та повертає змінну типу а. Дуже цікаво визначено поліморфну ​​функцію без параметрів — undefined:

Цю функцію-константу використовують для позначення невизначеної величини будь-якого типу.

=> » Крім того, що імена операторів полягають у круглі дужки, визначення функції таке саме як і в префіксній нотації. Приклад:

Крім визначення функції в інфіксної нотації, часто буває необхідно вказати пріоритет оператора і тип асоціативності. У Haskell пріоритет задається цілим числом, що більше число, то вище пріоритет і тим раніше виконається оператор.

За асоціативністю оператори поділяються на асоціативні, асоціативні праворуч, асоціативні.зліва та неасоціативні. Деякий умовний оператор "\/":

  • асоціативний праворуч, якщо вираз a/b/c обчислюють як a/(b/c)
  • асоціативний зліва, якщо вираз a/b/c обчислюють як (a/b)/c
  • асоціативний, якщо вираз a/b\/c можна обчислювати в будь-якому порядку
  • неасоціативний, якщо вираз a/b\/c заборонено записувати без дужок
В Haskell:
  • infixr – асоціативність праворуч
  • infixl – асоціативність зліва
  • infix – неасоціативний оператор
Отже, як ми напишемо оператор з урахуванням пріоритету та асоціативності:

Пріоритети та асоціативність стандартних операторів з прелюдії:

Отже, чому в Haskell немає функції двох і більше аргументів? Розглянемо функцію:

Функція plus має один аргумент. Цей аргумент – пара чисел. Зазвичай функції в Haskell записують у вигляді:

І ця функція також має один аргумент (а не два, як можна було б подумати), цей аргумент — число типу Integer. Таким чином з'являється можливість застосовувати аргументи по одному. У цьому полягає принцип карірування (на ім'я американського логіка Haskell B. Curry). Якщо «годувати» таку функцію число, то отримаємо ще одну функцію. У цьому нескладно переконатись на простому прикладі:

Цей прийом називають частковим застосуванням функції.

У прелюдії визначені спеціальні функції curry та uncurry, що приводять функції до карингової форми та назад:

Яку функцію ми не написали б, аргумент виходить лише один. Однак каринговий вигляд, за рідкісним винятком, кращий. Каррингові функції, окрім того, що зменшують кількість дужок, привносять чимало плюшок при використанні. У цьому ми переконаємось у наступних лекціях. А сьогодні все.Прінаписанні тексту я спирався на конспекти лекцій Сергія Михайловича Абрамова.Дякую за увагу!

Хардкорна конфа за С++. Ми запрошуємо лише профі.