Haskell — это функциональный язык программирования, разработанный специально для обработки символьных вычислений и списков.
Данная статья носит обучающий характер и предназначена для новичков, стремящихся понять основные положения Haskell.
Что такое Haskell?
Haskell — широко распространенный чистый функциональный язык.
Функциональные программы больше подходят для использования в многопоточной среде и предусматривают параллельное выполнение, добиваясь более точной и эффективной производительности. В традиционных языках программирования мы инструктируем компилятор, как выполнить то или иное действие.
Но в Haskell действует иной принцип — здесь мы говорим, что делать. Кроме того, это ленивый язык, поэтому программа не выполняет код, если считает его необязательным.
Программа на Haskell — это не что иное, как ряд выполняющихся функций.
Haskell — строго типизированный язык. Это значит, что компилятор достаточно сообразителен, чтобы определить тип объявленной переменной. Следовательно, у нас нет необходимости явно указывать ее тип.
Настройка среды Haskell
Для настройки среды Haskell на компьютере Windows перейдите по этой ссылке на официальный веб-сайт и загрузите соответствующий установочный пакет.
Если же необходимо настроить эту среду в системе MAC, воспользуйтесь следующей ссылкой для перехода на официальный сайт и загрузите установщик Mac.
Процесс настройки в Linux выглядит следующим образом:
$ sudo apt-get install haskell-platform
Начало работы с Haskell
Вы без особого труда начнете программировать на Haskell — достаточно лишь ввести следующую команду в терминал:
$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude>
Вот теперь можно писать код.
Пример программы
Это простой пример, демонстрирующий динамизм Haskell. Рассмотрим следующий код:
Prelude> main = putStrLn «Hello Medium»
Его результат:
Hello Medium
Основные операции
Haskell — настолько смышленый язык, что распознает число как число. Поэтому вам не нужно извне указывать его тип, как это обычно принято в других языках программирования.
Пример:
Prelude> 4*4
Результат:
Prelude> 16
Символы
Наряду с числами, Haskell способен распознавать символы, поступающие в него при вводе данных.
Для отображения типа переменной можно ввести следующую строку кода
Prelude> :t "a"
и получить вот такой результат:
"a" :: [Char]
Строки
Строка — это не что иное, как набор символов. Создадим следующую строку
Prelude> "Hello Medium"
и увидим:
"Hello Medium"
Если нужно узнать тип этой строки, снова воспользуйтесь :t
:
Prelude> :t "Hello Medium"
В результате:
"Hello Medium" :: [Char]
Как уже ранее упоминалось, строка — это просто набор символов, поэтому она вернется в качестве типа данных Char
.
Логические типы данных
С логическими типами всё также просто и понятно, как и с другими данными. Следующий пример демонстрирует некоторые из них.
Prelude> True && True
или
Prelude> True && False
Списки
Подобно другим типам данных в Haskell, List
также обладает не меньшей практической значимостью. Как следует из примера, [a,b,c] представляет собой список символов. Следовательно, List
— это набор элементов одного и того же типа данных, разделенных запятыми. Создадим свой список:
Prelude> x = [1,2,3,4,5]
Результат:
[1,2,3,4,5]
Метод Length
Списки имеют несколько методов. Допустим, у вас есть список x, длину которого необходимо определить. Следующий метод как раз для вас:
Prelude> length x
Метод Reverse
Этот метод используется для обращения порядка следования элементов списка:
Prelude> reverse x
Метод Add
Для добавления элемента в список можно использовать оператор ++
:
Prelude> x ++ y
Этот код объединяет два списка: x и y.
Метод Delete
Используйте drop
для удаления одного элемента из списка:
Prelude>`drop n xs
Кортеж
Haskell предоставляет еще один способ объявления нескольких значений в одном типе данных. Речь идет о кортеже, который можно рассматривать как список. Однако между ними есть ряд технических отличий.
Кортеж содержит фиксированное число элементов. Он относится к неизменяемым типам. Создается кортеж следующим образом:
Prelude> (8,16,'b')
В итоге:
(8,16,'b')
Это кортеж содержит три элемента: два числа и символ.
Как и в случае со списками, у кортежей есть методы, например, для определения в нем первого или последнего элемента.
Первый элемент
Для извлечения первого элемента кортежа используется следующий метод:
Prelude> fst (16, 8)
Его результат:
16
Методы Head and tail
Метод head
также предназначен для извлечения первого элемента кортежа:
Prelude> head (16, 8, 24, 32)
В итоге:
16
Метод tail
позволит вам извлечь не только последний или второй элемент кортежа, но и все его элементы за исключением первого:
Prelude> tail(16, 8, 24, 32)
и в результате:
[8, 24, 32]
Условные инструкции
Условные инструкции — это программная возможность, позволяющая применять условие в процессе работы кода. Программист может выполнить набор инструкций в зависимости от предварительно заданного условия.
Haskell располагает такими условными инструкциями, как:
- инструкция if-else;
- вложенная инструкция if-else.
Инструкция if-else
Синтаксис выражений if
выглядит следующим образом:
if <condition> then <true-value> else <false-value>
Функции
Функции играют важную роль в Haskell, поскольку он является языком функционального программирования. Подобно другим языкам, в нем существует определение и объявление функций.
Следующий небольшой пример с функцией add
поможет нам подробно разобраться в сути этой концепции.
add :: Integer -> Integer -> Integer --function declaration
add x y = x + y --function definition
main = do
putStrLn "The addition of the two numbers is:"
print(add 2 5) --calling a function
Результат:
The addition of the two numbers is:
7
Сопоставление с образцом
Этот метод предполагает сопоставление с конкретным типом выражения и позволяет упростить код.
Рассмотрим следующий блок кода:
fact :: Int -> Int
fact 0 = 1
fact n = n * fact ( n - 1 )
main = do
putStrLn "The factorial of 4 is:"
print (fact 4)
В данном примере метод сопоставления с образцом использовался для вычисления факториала числа.
Охранные выражения
Принцип охранных выражений очень похож на сопоставление с образцом, но вот используются они для тестирования свойств выражений. В следующем примере кода в программу факториала были внесены изменения с учетом концепции охранных выражений:
fact :: Integer -> Integer
fact n | n == 0 = 1
| n /= 0 = n * fact (n-1)
main = do
putStrLn "The factorial of 4 is:"
print (fact 4)
Рекурсия
Рекурсия — это ситуация, при которой функция вызывает саму себя. Haskell не предоставляет возможность повторять цикл выражения более одного раза.
Он предлагает вам разбить всю функциональность на несколько разных функций и реализовать ее, используя рекурсию.
В данном примере для вычисления факториала 4 использовались оба метода: сопоставление с образцом и рекурсия.
fact :: Int -> Int
fact 0 = 1
fact n = n * fact ( n - 1 )
main = do
putStrLn "The factorial of 4 is:"
print (fact 4)
Лямбда-выражения
Функция, не имеющая определения, получила название лямбда-функции. Она обозначается символом \
.
main = do
putStrLn "The successor of 5 is:"
print ((\x -> x + 1) 5)
Модули
Если у вас был опыт программирования на Java, то вы в курсе, что все классы объединяются в папки, так называемые пакеты. Подобно этому и Haskell можно рассматривать как набор модулей.
Например, предлагаю вашему вниманию модуль list:
import Data.List
И сразу функциональности List
попадают в ваше распоряжение.
Среди других модулей можно выделить следующие:
- модуль
Char
- модуль
Map
- модуль
Set
Пользовательские модули
Создадим модуль Custom и определим в нем несколько функций.
module Custom (
showEven,
showBoolean
) where
showEven:: Int-> Bool
showEven x = do
if x 'rem' 2 == 0
then True
else False
showBoolean :: Bool->Int
showBoolean c = do
if c == True
then 1
else 0
А теперь импортируем его программу, выполнив следующее действие:
import Custom
main = do
print(showEven 4)
print(showBoolean True)
Полезные ресурсы:
Заключение
Надеюсь, что материал данной статьи помог вам составить общее представление о Haskell, и теперь вы без особого труда сможете написать на нем простой код.
Полагаю, что овладение Haskell упростит вам изучение других функциональных языков программирования.
Читайте также:
- Использование инверсии зависимостей в Go
- Встроенная база данных Python
- Программируем робота E-puck в симуляторе Webots
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Bryan Dijkhuizen: An Introduction to Functional Programming in Haskell