Відмінності між версіями «Haskell»

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку
[перевірена версія][перевірена версія]
(Не показані 2 проміжні версії цього користувача)
Рядок 11: Рядок 11:
 
influenced = [[Clojure]], [[C#]], [[F#]], [[Java Generics]], [[LINQ]], [[Perl 6]], [[Python]], [[Scala]]
 
influenced = [[Clojure]], [[C#]], [[F#]], [[Java Generics]], [[LINQ]], [[Perl 6]], [[Python]], [[Scala]]
 
}}
 
}}
'''Haskell''' (укр. ''Хаскель'' або ''Хаскелл'') — стандартизована, винятково [[Функційне програмування|функційна]] [[мова програмування]] з нестрогою семантикою. Названа на честь американського математика [[Каррі Хаскелл|Хаскелла Каррі]], роботи якого в галузі математичної логіки є базовими для функційного програмування. Хаскель базується на [[Лямбда числення|лямбда численні]]. Найважливішими реалізаціями є [[компілятор]] ''Glasgow Haskell Compiler'' (GHC) та оснований на ньому компілятор GHCJS, що компілює Хаскель-код у скрипт мовою JavaScript. Історично важливим також є [[інтерпретатор]] ''Hugs'', але на сьогодні він не підтримується.
+
'''Haskell''' (укр. ''Гаскель'' або ''Гаскелл'') — стандартизована, винятково [[Функційне програмування|функційна]] [[мова програмування]] з нестрогою семантикою. Названа на честь американського математика [[Гаскелл Каррі|Гаскелла Каррі]], роботи якого в галузі математичної логіки є базовими для функційного програмування. Гаскель базується на [[Лямбда числення|лямбда численні]]. Найважливішими реалізаціями є [[компілятор]] ''Glasgow Haskell Compiler'' (GHC) та оснований на ньому компілятор GHCJS, що компілює Гаскель-код у скрипт мовою JavaScript. Історично важливим також є [[інтерпретатор]] ''Hugs'', але на сьогодні він не підтримується.
   
 
== Історія ==
 
== Історія ==
   
На кінець 1980-тих років, вже існували деякі функційні мови програмування, з власними перевагами та недоліками. Для того, аби наука отримала єдину основу для досліджень, слід було розробити стандартизовану сучасну функційну мову програмування. Тоді планувалось використати мову програмування [[Міранда (мова програмування)|Міранда]] як вихідний варіант; однак, її розробники були в цьому не зацікавлені. Так, в [[1990]] році і з'явилась мова програмування Хаскель 1.0.
+
На кінець 1980-тих років, вже існували деякі функційні мови програмування, з власними перевагами та недоліками. Для того, аби наука отримала єдину основу для досліджень, слід було розробити стандартизовану сучасну функційну мову програмування. Тоді планувалось використати мову програмування [[Міранда (мова програмування)|Міранда]] як вихідний варіант; однак, її розробники були в цьому не зацікавлені. Так, в [[1990]] році і з'явилась мова програмування Гаскель 1.0.
   
Поточна версія мови програмування є переробленим варіантом стандарта Хаскель-98 [[1999]] року. Зараз Хаскель є функційною мовою програмування, яка широко використовується як для досліджень, так і для реалізації комерційних проектів. Крім того, існує велика кількість варіантів мови програмування: ''Parallel Haskell'', ''Distributed Haskell'' (раніше Gofin), ''Eager Haskell'', ''Eden'', ''DNA-Haskell'' і, також, [[об'єктно-орієнтоване програмування|об'єктно-орієнтовані]] варіанти (''Haskell++'', ''O'Haskell'', ''Mondrian''). Для інших, Хаскель був прикладом при розробці мови програмування. Наприклад, у випадку мови програмування [[Пайтон]], було запозиченно концепцію Лямбда-нотації та синтаксис роботи із списками.
+
Поточна версія мови програмування є переробленим варіантом стандарта Гаскель-98 [[1999]] року. Зараз Гаскель є функційною мовою програмування, яка широко використовується як для досліджень, так і для реалізації комерційних проектів. Крім того, існує велика кількість варіантів мови програмування: ''Parallel Haskell'', ''Distributed Haskell'' (раніше Gofin), ''Eager Haskell'', ''Eden'', ''DNA-Haskell'' і, також, [[об'єктно-орієнтоване програмування|об'єктно-орієнтовані]] варіанти (''Haskell++'', ''O'Haskell'', ''Mondrian''). Для інших, Гаскель був прикладом при розробці мови програмування. Наприклад, у випадку мови програмування [[Пайтон]], було запозиченно концепцію Лямбда-нотації та синтаксис роботи із списками.
   
 
== Застосування ==
 
== Застосування ==
Незважаючи на порівняно невелику спільноту Хаскеля, він уже показав свої сильні сторони у декількох проектах. [[Pugs]] — реалізація довгоочікуваної мови програмування [[Perl 6]] з інтерпретатором та компілятором, які показали корисність Хаскеля лише через кілька місяців від написання; також, GHC часто використовується як випробувальний стенд для передових можливостей функційного програмування та оптимізацій. [[Darcs]] — це [[система контролю версій]], яка має кілька інноваційних особливостей. [[Linspire]] GNU/Linux використовує Хаскель для розробки системних утиліт.<ref>{{cite web|url=http://urchin.earth.li/pipermail/debian-haskell/2006-May/000169.html|title=Linspire/Freespire Core OS Team and Haskell|work=Debian Haskell mailing list|year=2006|month=May|archiveurl=http://www.webcitation.org/6HdRy7mfs|archivedate=2013-06-25}}</ref> [[xmonad]] — це [[менеджер вікон]] для [[X Window System]], цілковито написанний на Хаскелі.
+
Незважаючи на порівняно невелику спільноту Гаскеля, він уже показав свої сильні сторони у декількох проектах. [[Pugs]] — реалізація довгоочікуваної мови програмування [[Perl 6]] з інтерпретатором та компілятором, які показали корисність Гаскеля лише через кілька місяців від написання; також, GHC часто використовується як випробувальний стенд для передових можливостей функційного програмування та оптимізацій. [[Darcs]] — це [[система контролю версій]], яка має кілька інноваційних особливостей. [[Linspire]] GNU/Linux використовує Гаскель для розробки системних утиліт.<ref>{{cite web|url=http://urchin.earth.li/pipermail/debian-haskell/2006-May/000169.html|title=Linspire/Freespire Core OS Team and Haskell|work=Debian Haskell mailing list|year=2006|month=May|archiveurl=http://www.webcitation.org/6HdRy7mfs|archivedate=2013-06-25}}</ref> [[xmonad]] — це [[менеджер вікон]] для [[X Window System]], цілковито написанний на Гаскелі.
   
 
== Особливості ==
 
== Особливості ==
 
=== Робота програм ===
 
=== Робота програм ===
   
* Хаскель є чистою [[Функційна мова програмування|функційною мовою програмування]]. Функції не мають жодних [[побічні ефекти (програмування)|побічних ефектів]]. Це означає, що для одних і тих самих значень вхідних параметрів завжди повертатимуться однакові результати обчислень.
+
* Гаскель є чистою [[Функційна мова програмування|функційною мовою програмування]]. Функції не мають жодних [[побічні ефекти (програмування)|побічних ефектів]]. Це означає, що для одних і тих самих значень вхідних параметрів завжди повертатимуться однакові результати обчислень.
   
 
* Функційні мови програмування відрізняються від імперативних мов програмування тим, що програміст не повинен визначати порядок обчислення функцій. Розробнику слід лише описати залежність між даними, а транслятор вже самотужки визначає порядок обчислень на імперативному обчислювальному пристрої.
 
* Функційні мови програмування відрізняються від імперативних мов програмування тим, що програміст не повинен визначати порядок обчислення функцій. Розробнику слід лише описати залежність між даними, а транслятор вже самотужки визначає порядок обчислень на імперативному обчислювальному пристрої.
Рядок 37: Рядок 37:
 
* Усунення проблем від наявності побічних ефектів, значною мірою полегшує спостереження за послідовністю роботи програми.
 
* Усунення проблем від наявності побічних ефектів, значною мірою полегшує спостереження за послідовністю роботи програми.
   
* Хаскель є не строгою мовою програмування. Обчислюються лише вирази, значення яких необхідне для обчислення результатів.
+
* Гаскель є не строгою мовою програмування. Обчислюються лише вирази, значення яких необхідне для обчислення результатів.
 
first x y = x
 
first x y = x
 
square x = x * x
 
square x = x * x
Рядок 48: Рядок 48:
 
=== Система типів ===
 
=== Система типів ===
   
* Хаскель є сильно типізованою мовою програмування. Розрізняються цілі, числа з плаваючою комою, рядкові, та інші типи даних.
+
* Гаскель є сильно типізованою мовою програмування. Розрізняються цілі, числа з плаваючою комою, рядкові, та інші типи даних.
   
 
* Підримуються змінні типів. Завдяки цьому, можна робити узагальнені формулювання функцій. У випадку, коли така загальна функція застосовується до змінних з конкретним типом, автоматично визначаються і типи результатів решти обчислень.
 
* Підримуються змінні типів. Завдяки цьому, можна робити узагальнені формулювання функцій. У випадку, коли така загальна функція застосовується до змінних з конкретним типом, автоматично визначаються і типи результатів решти обчислень.
Рядок 59: Рядок 59:
 
map toUpper :: [Char] -> [Char]
 
map toUpper :: [Char] -> [Char]
   
* Із самого початку Хаскель є мовою програмування зі [[статична типізація|статичною типізацією]], хоча, існують варіанти з [[динамічна типізація|динамічною типізацією]]. Це значить, що для більшості обчислень, типи аргументів відомі вже на етапі трансляції. Це допомагає уникнути очевидних помилок ще до початку обчислень.
+
* Із самого початку Гаскель є мовою програмування зі [[статична типізація|статичною типізацією]], хоча, існують варіанти з [[динамічна типізація|динамічною типізацією]]. Це значить, що для більшості обчислень, типи аргументів відомі вже на етапі трансляції. Це допомагає уникнути очевидних помилок ще до початку обчислень.
   
* Хаскель підтримує [[функції вищого порядку]] (''функціонали''). Тобто, функції, які можуть приймати як аргументи й повертати як результати функції. Одним із прикладів, є функція <tt>map</tt>, яка обчислює надану функцію <tt>f</tt> для кожного елемента одного типу (тут списка).
+
* Гаскель підтримує [[функції вищого порядку]] (''функціонали''). Тобто, функції, які можуть приймати як аргументи й повертати як результати функції. Одним із прикладів, є функція <tt>map</tt>, яка обчислює надану функцію <tt>f</tt> для кожного елемента одного типу (тут списка).
   
 
map :: (a -> b) -> [a] -> [b]
 
map :: (a -> b) -> [a] -> [b]
Рядок 74: Рядок 74:
 
:В прикладі наведено структуру даних [[дерево (структура даних)|дерев]] з наповенене [[цілі числа|цілими числами]]. Таким чином, дерево (<tt>Tree Int</tt>) складається або із листа (<tt>Leaf Int</tt>), або відгалуження (<tt>Branch Int t1 t2</tt>), де <tt>t1</tt> та <tt>t2</tt> містять піддерева, що мають структуру даних <tt>Tree Int</tt>. Для визначення цієї структури даних, треба, також, визначити конструктор <tt>Leaf</tt> з одним параметром, та конструктор <tt>Branch</tt> з трьома параметрами.
 
:В прикладі наведено структуру даних [[дерево (структура даних)|дерев]] з наповенене [[цілі числа|цілими числами]]. Таким чином, дерево (<tt>Tree Int</tt>) складається або із листа (<tt>Leaf Int</tt>), або відгалуження (<tt>Branch Int t1 t2</tt>), де <tt>t1</tt> та <tt>t2</tt> містять піддерева, що мають структуру даних <tt>Tree Int</tt>. Для визначення цієї структури даних, треба, також, визначити конструктор <tt>Leaf</tt> з одним параметром, та конструктор <tt>Branch</tt> з трьома параметрами.
   
* Функції дозволяють каррінг. В той час, як в інших мовах програмування, як аргументи функції передаються [[кортеж]]і, тобто, типи функцій мають вигляд <tt>(a,b) -> c</tt>, в Хаскель прийнято використовувати Каррі-подібну форму <tt>a -> b -> c</tt>. Завдяки цьому, стає можливим часткове обчислення значення функцій. Вираз <tt>map toUpper</tt> є прикладом часткового обчислення <tt>map</tt>, оскільки, він визначає функцію, а саме, функцію, що переводить всі літери у верхній регістр.
+
* Функції дозволяють каррінг. В той час, як в інших мовах програмування, як аргументи функції передаються [[кортеж]]і, тобто, типи функцій мають вигляд <tt>(a,b) -> c</tt>, в Гаскель прийнято використовувати Каррі-подібну форму <tt>a -> b -> c</tt>. Завдяки цьому, стає можливим часткове обчислення значення функцій. Вираз <tt>map toUpper</tt> є прикладом часткового обчислення <tt>map</tt>, оскільки, він визначає функцію, а саме, функцію, що переводить всі літери у верхній регістр.
   
* Хаскель підтримує класи типів. Завдяки класифікації типів, можна визначити спільні операції для типів одного класу. В сигнатурах функцій можуть бути присутні як аргументи конкретного типу, приміром, <tt>Char</tt> та безтиповими змінними, визначатись аргументи з явно заданими обмеженнями типів.
+
* Гаскель підтримує класи типів. Завдяки класифікації типів, можна визначити спільні операції для типів одного класу. В сигнатурах функцій можуть бути присутні як аргументи конкретного типу, приміром, <tt>Char</tt> та безтиповими змінними, визначатись аргументи з явно заданими обмеженнями типів.
 
:Всі застосування методу з класами типів мають однакове ім'я. Це, в деякому сенсі, відповідає [[перегрузка|перегрузці]] функцій. Ім'я певної функції залежить від типів аргументів. Наприклад, метод <tt>==</tt> класу <tt>Eq</tt> порівнює як пару цифр, так і пару рядків. Однак, робота цього методу залежить від типів аргументів.
 
:Всі застосування методу з класами типів мають однакове ім'я. Це, в деякому сенсі, відповідає [[перегрузка|перегрузці]] функцій. Ім'я певної функції залежить від типів аргументів. Наприклад, метод <tt>==</tt> класу <tt>Eq</tt> порівнює як пару цифр, так і пару рядків. Однак, робота цього методу залежить від типів аргументів.
   
Рядок 83: Рядок 83:
 
Розрізняється реєстр літер. Ідентифікатори, що починаються з великих літер, означають типи та конструктори. Ідентифікатори, що починаються з малої літери, означають змінні, функції, та параметри.
 
Розрізняється реєстр літер. Ідентифікатори, що починаються з великих літер, означають типи та конструктори. Ідентифікатори, що починаються з малої літери, означають змінні, функції, та параметри.
   
* Хаскель пропонує ряд [[синтаксичний цукор|синтаксичних особливостей]]. Вони мають допомагати висловлювати все відповідно до функційної парадигми.
+
* Гаскель пропонує ряд [[синтаксичний цукор|синтаксичних особливостей]]. Вони мають допомагати висловлювати все відповідно до функційної парадигми.
   
 
Замість
 
Замість
Рядок 99: Рядок 99:
 
=== Програмування ===
 
=== Програмування ===
   
* Хаскель підтримує [[пошук по шаблонах]]. Тобто, як формальні параметри можна передавати шаблони. При цьому, описані шаблони стають аргументами функції.
+
* Гаскель підтримує [[пошук по шаблонах]]. Тобто, як формальні параметри можна передавати шаблони. При цьому, описані шаблони стають аргументами функції.
 
fac :: Integer -> Integer
 
fac :: Integer -> Integer
 
fac 0 = 1
 
fac 0 = 1
Рядок 108: Рядок 108:
 
=== Модулі ===
 
=== Модулі ===
   
Хаскель, також, має систему модулів. Існує велика кількість модулів, в яких реалізовано багато корисних функцій. Один із найповніших переліків існуючих модулів міститься в [http://www.zvon.org/other/haskell/Outputglobal/index.html Haskell Reference]{{ref-en|}}.
+
Гаскель, також, має систему модулів. Існує велика кількість модулів, в яких реалізовано багато корисних функцій. Один із найповніших переліків існуючих модулів міститься в [http://www.zvon.org/other/haskell/Outputglobal/index.html Haskell Reference]{{ref-en|}}.
   
 
Для того, аби використати модуль, необхідно його імпортувати. Це робиться з використанням ключового слова <tt>import</tt>:
 
Для того, аби використати модуль, необхідно його імпортувати. Це робиться з використанням ключового слова <tt>import</tt>:
Рядок 131: Рядок 131:
 
=== Факторіал ===
 
=== Факторіал ===
   
Елегантне визначення функції [[факторіал]]у, яке використовує нотацію Хаскеля для списків:
+
Елегантне визначення функції [[факторіал]]у, яке використовує нотацію Гаскеля для списків:
   
 
fac :: Integer -> Integer
 
fac :: Integer -> Integer
Рядок 152: Рядок 152:
 
=== Швидке сортування ===
 
=== Швидке сортування ===
   
[[Алгоритм]] [[Швидке сортування|швидкого сортування]] записується мовою Хаскель так:
+
[[Алгоритм]] [[Швидке сортування|швидкого сортування]] записується мовою Гаскель так:
 
qsort :: Ord a => [a] -> [a]
 
qsort :: Ord a => [a] -> [a]
 
qsort [] = []
 
qsort [] = []
Рядок 169: Рядок 169:
 
* Simon Thompson: ''Haskell — The Craft of Functional Programming'', 1999, Addison-Wesley, ISBN 0-201-34275-8
 
* Simon Thompson: ''Haskell — The Craft of Functional Programming'', 1999, Addison-Wesley, ISBN 0-201-34275-8
 
* Paul Hudak: ''The Haskell School of Expression — Learning Functional Programming Through Multimedia.'', 2000, Cambridge University Press, ISBN 0-521-64338-4
 
* Paul Hudak: ''The Haskell School of Expression — Learning Functional Programming Through Multimedia.'', 2000, Cambridge University Press, ISBN 0-521-64338-4
* Міран Ліповача: [http://haskell.trygub.com ''Вивчить собі Хаскела на велике щастя!''] (переклад українською http://learnyouahaskell.com)
+
* Міран Ліповача: [http://haskell.trygub.com ''Вивчить собі Гаскела на велике щастя!''] (переклад українською http://learnyouahaskell.com)
   
 
== Посилання ==
 
== Посилання ==
* http://www.haskell.org/ — Центральний портал мови програмування Хаскель.
+
* http://www.haskell.org/ — Центральний портал мови програмування Гаскель.
* http://www.haskell.org/learning.html — Корисна інформація для вивчення Хаскель.
+
* http://www.haskell.org/learning.html — Корисна інформація для вивчення Гаскель.
* http://www.haskell.org/hugs/ — Hugs 98, безкоштовний інтерпретатор Хаскель.
+
* http://www.haskell.org/hugs/ — Hugs 98, безкоштовний інтерпретатор Гаскель.
* http://haskell.readscheme.org/ — Наукова література про Хаскель.
+
* http://haskell.readscheme.org/ — Наукова література про Гаскель.
* http://haskell.trygub.com — сайт-книга "Вивчить собі Хаскела на велике щастя!"
+
* http://haskell.trygub.com — сайт-книга "Вивчить собі Гаскела на велике щастя!"
   
 
== Див. також ==
 
== Див. також ==
 
* [[ML (мова програмування)|ML]]
 
* [[ML (мова програмування)|ML]]
* [[Pugs]] (імплементація [[Перл]] версії 6 на Хаскель)
+
* [[Pugs]] (імплементація [[Перл]] версії 6 на Гаскель)
 
* [[Функційне програмування]]
 
* [[Функційне програмування]]
   

Версія за 05:00, 12 лютого 2017

Haskell
Haskell-Logo.svg
Парадигма:функційна, не строга, модульна
Дата появи:1990
Система типізації:сильна, статична
Основні реалізації:GHC, GHCJS, Hugs, NHC, JHC, Yhc
Діалекти:--
Під впливом від:APL, Lisp, Miranda, ML, Gofer, Scheme
Вплинула на:Clojure, C#, F#, Java Generics, LINQ, Perl 6, Python, Scala
Сторінка інтернет:{{{website}}}

Haskell (укр. Гаскель або Гаскелл) — стандартизована, винятково функційна мова програмування з нестрогою семантикою. Названа на честь американського математика Гаскелла Каррі, роботи якого в галузі математичної логіки є базовими для функційного програмування. Гаскель базується на лямбда численні. Найважливішими реалізаціями є компілятор Glasgow Haskell Compiler (GHC) та оснований на ньому компілятор GHCJS, що компілює Гаскель-код у скрипт мовою JavaScript. Історично важливим також є інтерпретатор Hugs, але на сьогодні він не підтримується.

Історія

На кінець 1980-тих років, вже існували деякі функційні мови програмування, з власними перевагами та недоліками. Для того, аби наука отримала єдину основу для досліджень, слід було розробити стандартизовану сучасну функційну мову програмування. Тоді планувалось використати мову програмування Міранда як вихідний варіант; однак, її розробники були в цьому не зацікавлені. Так, в 1990 році і з'явилась мова програмування Гаскель 1.0.

Поточна версія мови програмування є переробленим варіантом стандарта Гаскель-98 1999 року. Зараз Гаскель є функційною мовою програмування, яка широко використовується як для досліджень, так і для реалізації комерційних проектів. Крім того, існує велика кількість варіантів мови програмування: Parallel Haskell, Distributed Haskell (раніше Gofin), Eager Haskell, Eden, DNA-Haskell і, також, об'єктно-орієнтовані варіанти (Haskell++, O'Haskell, Mondrian). Для інших, Гаскель був прикладом при розробці мови програмування. Наприклад, у випадку мови програмування Пайтон, було запозиченно концепцію Лямбда-нотації та синтаксис роботи із списками.

Застосування

Незважаючи на порівняно невелику спільноту Гаскеля, він уже показав свої сильні сторони у декількох проектах. Pugs — реалізація довгоочікуваної мови програмування Perl 6 з інтерпретатором та компілятором, які показали корисність Гаскеля лише через кілька місяців від написання; також, GHC часто використовується як випробувальний стенд для передових можливостей функційного програмування та оптимізацій. Darcs — це система контролю версій, яка має кілька інноваційних особливостей. Linspire GNU/Linux використовує Гаскель для розробки системних утиліт.[1] xmonad — це менеджер вікон для X Window System, цілковито написанний на Гаскелі.

Особливості

Робота програм

  • Функційні мови програмування відрізняються від імперативних мов програмування тим, що програміст не повинен визначати порядок обчислення функцій. Розробнику слід лише описати залежність між даними, а транслятор вже самотужки визначає порядок обчислень на імперативному обчислювальному пристрої.
  • Відсутні будь-які імперативні конструкції мови програмування. Завдяки монадам можливо виконувати операції вводу-виводу, інші обчислення, які вимагають збереження стану, в чисто функційному вигляді.
  • Відсутні оператори зміни значення змінних. Через це, відсутня різниця між константами та змінними. Як наслідок, відпадає необхідність у декларації const або final, які є, наприклад, в мовах програмування Сі та Java відповідно.
  • Усунення проблем від наявності побічних ефектів, значною мірою полегшує спостереження за послідовністю роботи програми.
  • Гаскель є не строгою мовою програмування. Обчислюються лише вирази, значення яких необхідне для обчислення результатів.
 first x y = x
 square x = x * x
Функція first при виклику з двома параметрами повертає значення першого. При виклику first x (3+7) обчислення значення суми (3+7) не потрібне для обчислення результата, і, тому, може не виконуватись.
Функція square повертає значення квадрата переданого параметра. При обчисленні square (3+5), функція матиме обчислити (3+5)*(3+5), однак, подвійне обчислення (3+5) не є оптимальним, і має уникатись.
Реалізація лінивих обчислень полегшується відсутністю побічних ефектів та строгим дотриманням парадигми функційного програмування.

Система типів

  • Гаскель є сильно типізованою мовою програмування. Розрізняються цілі, числа з плаваючою комою, рядкові, та інші типи даних.
  • Підримуються змінні типів. Завдяки цьому, можна робити узагальнені формулювання функцій. У випадку, коли така загальна функція застосовується до змінних з конкретним типом, автоматично визначаються і типи результатів решти обчислень.
Функція map виконує надану функцію для кожного елемента зі списку. Її тип має вигляд:
 map :: (a -> b) -> [a] -> [b]
У випадку, якщо map буде викликано із функцією toUpper, яка має тип Char -> Char, вона матиме тип:
 map toUpper :: [Char] -> [Char]
  • Із самого початку Гаскель є мовою програмування зі статичною типізацією, хоча, існують варіанти з динамічною типізацією. Це значить, що для більшості обчислень, типи аргументів відомі вже на етапі трансляції. Це допомагає уникнути очевидних помилок ще до початку обчислень.
  • Гаскель підтримує функції вищого порядку (функціонали). Тобто, функції, які можуть приймати як аргументи й повертати як результати функції. Одним із прикладів, є функція map, яка обчислює надану функцію f для кожного елемента одного типу (тут списка).
 map :: (a -> b) -> [a] -> [b]
 map f [] = []
 map f x:xs = f x : map f xs
 map square [1,2,3] = [square 1, square 2, square 3] = [1,4,9]
  • Підтримується визначення типів даних користувачами. Ці типи даних визначаються використанням конструкторів типів даних.
 data Tree Int = Leaf Int | Branch Int (Tree Int) (Tree Int)
В прикладі наведено структуру даних дерев з наповенене цілими числами. Таким чином, дерево (Tree Int) складається або із листа (Leaf Int), або відгалуження (Branch Int t1 t2), де t1 та t2 містять піддерева, що мають структуру даних Tree Int. Для визначення цієї структури даних, треба, також, визначити конструктор Leaf з одним параметром, та конструктор Branch з трьома параметрами.
  • Функції дозволяють каррінг. В той час, як в інших мовах програмування, як аргументи функції передаються кортежі, тобто, типи функцій мають вигляд (a,b) -> c, в Гаскель прийнято використовувати Каррі-подібну форму a -> b -> c. Завдяки цьому, стає можливим часткове обчислення значення функцій. Вираз map toUpper є прикладом часткового обчислення map, оскільки, він визначає функцію, а саме, функцію, що переводить всі літери у верхній регістр.
  • Гаскель підтримує класи типів. Завдяки класифікації типів, можна визначити спільні операції для типів одного класу. В сигнатурах функцій можуть бути присутні як аргументи конкретного типу, приміром, Char та безтиповими змінними, визначатись аргументи з явно заданими обмеженнями типів.
Всі застосування методу з класами типів мають однакове ім'я. Це, в деякому сенсі, відповідає перегрузці функцій. Ім'я певної функції залежить від типів аргументів. Наприклад, метод == класу Eq порівнює як пару цифр, так і пару рядків. Однак, робота цього методу залежить від типів аргументів.

Синтаксис

Розрізняється реєстр літер. Ідентифікатори, що починаються з великих літер, означають типи та конструктори. Ідентифікатори, що починаються з малої літери, означають змінні, функції, та параметри.

Замість

 readFile "input.txt" >>= writeFile "output.txt"

або

 readFile "input.txt" >>= (\content -> writeFile "output.txt" content)

можна також написати

 do content <- readFile "input.txt"
    writeFile "output.txt" content
  • Як символьні (такі як +, -, *, /, >, <), так і алфавітно-цифрові ідентифікатори (літери, цифри, апостроф) можуть використовуватись і як назви функцій, і як інфіксні та постфіксні оператори. Наприклад, можна писати:
 a + b      ==  (+) a b
 a `div` b  ==  div a b

Програмування

  • Гаскель підтримує пошук по шаблонах. Тобто, як формальні параметри можна передавати шаблони. При цьому, описані шаблони стають аргументами функції.
 fac :: Integer -> Integer
 fac 0 = 1
 fac n = n * fac (n-1)
Функція fac обчислює факторіал числа. При виклику функції з параметром, що дорівнює 0, буде повернута 1. Для всіх інших випадків, обчислення факторіала відбувається шляхом рекурсивного виклику n*fac(n-1). В цьому прикладі, 0 та 1 є шаблонами, від збігу з якими залежить результат обчислень.

Модулі

Гаскель, також, має систему модулів. Існує велика кількість модулів, в яких реалізовано багато корисних функцій. Один із найповніших переліків існуючих модулів міститься в Haskell Reference(англ.).

Для того, аби використати модуль, необхідно його імпортувати. Це робиться з використанням ключового слова import:

 import List
 import Maybe

Різні модулі можуть містити функції та типи з однаковими іменами. Ці ідентифікатори можна розрізняти шляхом:

  • імпортування лише одного ідентифікатора,
 import Data.List(delete)
 x = delete 'a' "abc 
  • використанням повного (разом із модулем) імені ідентифікатора:
 import qualified Data.List
 x = Data.List.delete 'a' "abc 

або

 import qualified Data.List as List
 x = List.delete 'a' "abc"

Можливим, але не бажаним є приховування ідентифікаторів деклараціями hiding.

Приклади

Факторіал

Елегантне визначення функції факторіалу, яке використовує нотацію Гаскеля для списків:

 fac :: Integer -> Integer
 fac n = product [1..n]

Числа Фібоначчі

Наївна реалізація функції обчислення n числа з Послідовності Фібоначчі:

 fib :: Integer -> Integer
 fib 0 = 0
 fib 1 = 1
 fib n = fib (n - 2) + fib (n - 1)

Швидша реалізація обчислення послідовності:

 fibs :: [Integer]
 fibs = 0 : 1 : (zipWith (+) fibs (tail fibs))


Швидке сортування

Алгоритм швидкого сортування записується мовою Гаскель так:

 qsort :: Ord a => [a] -> [a]
 qsort []     = []
 qsort (x:xs) = qsort [y | y <- xs, y < x] ++ [x] ++ qsort [y | y <- xs, y >= x]

У першому рядку визначається сигнатура функції qsort. В другому рядку визначається, що результат застосування функції для порожнього списка є також порожній список. В третьому рядку відбувається рекурсивне сортування непорожніх списків: перший елемент x береться як середній елемент результуючого списка. Перед ним сортуються всі менші, а після нього — всі більші елементи списка. Для того, аби вибрати всі менші та більші елементи ніж x із хвоста списка xs, використано описання списків.

Як і очікується від алгоритму швидкого сортування, середній асимптотичний час роботи цього алгоритму дорівнює а час роботи в найгіршому випдаку дорівнює . На відміну від звичайних реалізацій в імперативних мовах програмування, описана функція працює не перетираючи вхідний масив.

Виноски

  1. Linspire/Freespire Core OS Team and Haskell. Debian Haskell mailing list. May 2006. Архів оригіналу за 2013-06-25. 

Література

  • Why Functional Programming Matters by John Hughes, The Computer Journal, Vol. 32, No. 2, 1989, pp. 98 – 107. [1] Переваги функційного програмування. Наводяться приклади модульності програм на основі функцій вищого порядку та лінивих обчислень.
  • Simon Thompson: Haskell — The Craft of Functional Programming, 1999, Addison-Wesley, ISBN 0-201-34275-8
  • Paul Hudak: The Haskell School of Expression — Learning Functional Programming Through Multimedia., 2000, Cambridge University Press, ISBN 0-521-64338-4
  • Міран Ліповача: Вивчить собі Гаскела на велике щастя! (переклад українською http://learnyouahaskell.com)

Посилання

Див. також