Добрый дня, уважаемыее. Всегда трудно начинать. Трудно начать писать статью, трудно начать отношения с человеком. Очень трудно, бывает, начать изучать новый язык программирования, особенно, если этот язык рушит все представления и устои, которые у вас были, если он противоречит привычной картине мира и пытается сломать вам
Почему нельзя просто взять и пересесть на Haskell?
«Вы все испорчены императивным стилем!» — так сказал нам наш первый преподаватель функциональных языков, замечательный человек, ученый и организатор Сергей Михайлович Абрамов. И он был прав. Как же трудно было забыть про переменные, присваивания, алгоритмы и начать думать функциями. Вы можете сесть и написать программу на Haskell, без проблем. Вы можете построить вложенный цикл, использовать переменные и присваивания, да легко! Но, потом, вы посмотрите на свой код и скажете: «Кому нужна эта функциональщина? Да, я на си напишу и быстрее, и лучше».
А это все оттого, что нельзя переносить императивный стиль программирования в функциональный язык. Нельзя заставлять рыбу летать, а птицу плавать. Нельзя быть уткой, которая и плавать и летать толком не умеет. Нужно опуститься в функции с головой, нужно почувствовать их
Читайте прелюдию
Ответ прост. Всего два слова. Читайте прелюдию! Если вы хотите постичь и полюбить Haskell, если хотите научиться чистому функциональному стилю, читайте прелюдию.
Прелюдия (Prelude) — стандартная библиотека самых необходимых функций, определяется стандартом Haskell 98. Каждая строчка, каждая точка выверены и вылизаны, ничего лишнего и императивного там не находится. Читая прелюдию, ты испытываешь эмоции сравнимые с эмоциями при прочтении интересной фантастической книги.
Одно из моих любимых мест в прелюдии это раздел где описывается работа со списками.
Возьмем, например, функцию map.
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs
Вы помните — мы мыслим функциями.
Что есть функция map? На входе мы имеем некоторую функцию из множества A в множество B, и список элементов из множества A. На выходе должны получить список из множества B, путем применения функции к каждому элементу списка.
Эта функция является отличным примером одного из основных приемов работы в Haskell — паттерны. Map имеющая на входе параметры вида а f [] (функция и пустой список) возвратит пустой список. В остальных случаях f применится к первому элементу списка, получившийся элемент добавится (двоеточие) к списку, образованному путем применения функции map к хвосту списка.
Одно из главных достоинств Haskell — если вы сформулировали функцию на математическом языке, запрограммировать ее, как правило, дело нескольких минут.
Еще немножко примеров
А, вот, еще одно чудо: функции head и tail, ну, просто загляденье!
head :: [a] -> a
head (x:_) = x
head [] = error "Prelude.head: empty list"
tail :: [a] -> [a]
tail (_:xs) = xs
tail [] = error "Prelude.tail: empty list"
Думаю, тут даже объяснять нечего. Нижнее подчеркивание в паттернах Haskell расшифровывается как «все что угодно».
null :: [a] -> Bool
null [] = True
null (_:_) = False
Неужели, существуют люди, которым это не нравится?
А вот функция length.
length :: [a] -> Int
length [] = 0
length (_:l) = 1 + length l
А как в прелюдии определен класс Eq? Вы будете смеяться!
class Eq a where
(==), (/=) :: a -> a -> Bool
-- Minimal complete definition:
-- (==) or (/=)
x /= y = not (x == y)
x == y = not (x /= y)
Правда головокружительная красота?
О чем я?
Можно было бы привети много примеров кода, но зачем портить вам удовольствие?
Всем новичкам, всем кто хочет полюбить Haskell один совет — читайте прелюдию. Я читаю и стараюсь писать как в прелюдии. Хотя бы стремлюсь. Читая прелюдию я понял философию Haskell и полюбил этот язык, чего всем вам желаю!
Простите, за сумбур, наверное я не писатель, я очень плохо изложил все то, что было нужно, но мне очень хотелось поделиться с вами частичкой любви к Haskell и этим маленьким, но очень полезым советом. Читайте прелюдию!
Автор: serr