Добрый дня, уважаемые хабровчане. Всегда трудно начинать. Трудно начать писать статью, трудно начать отношения с человеком. Очень трудно, бывает, начать изучать новый язык программирования, особенно, если этот язык рушит все представления и устои, которые у вас были, если он противоречит привычной картине мира и пытается сломать вам мозг. Пример такого языка — Haskell.
«Вы все испорчены императивным стилем!» — так сказал нам наш первый преподаватель функциональных языков, замечательный человек, ученый и организатор Сергей Михайлович Абрамов. И он был прав. Как же трудно было забыть про переменные, присваивания, алгоритмы и начать думать функциями. Вы можете сесть и написать программу на Haskell, без проблем. Вы можете построить вложенный цикл, использовать переменные и присваивания, да легко! Но, потом, вы посмотрите на свой код и скажете: «Кому нужна эта функциональщина? Да, я на си напишу и быстрее, и лучше».
А это все оттого, что нельзя переносить императивный стиль программирования в функциональный язык. Нельзя заставлять рыбу летать, а птицу плавать. Нельзя быть уткой, которая и плавать и летать толком не умеет. Нужно опуститься в функции с головой, нужно почувствовать их мозгом костей. Только так вы полюбите этот языки не сможете писать ни на чем другом. Но как, как же это сделать?
Ответ прост. Всего два слова. Читайте прелюдию! Если вы хотите постичь и полюбить Haskell, если хотите научиться чистому функциональному стилю, читайте прелюдию.
Прелюдия (Prelude) — стандартная библиотека самых необходимых функций, определяется стандартом Haskell 98. Каждая строчка, каждая точка выверены и вылизаны, ничего лишнего и императивного там не находится. Читая прелюдию, ты испытываешь эмоции сравнимые с эмоциями при прочтении интересной фантастической книги.
Одно из моих любимых мест в прелюдии это раздел где описывается работа со списками.
Возьмем, например, функцию map.
Вы помните — мы мыслим функциями.
Что есть функция map? На входе мы имеем некоторую функцию из множества A в множество B, и список элементов из множества A. На выходе должны получить список из множества B, путем применения функции к каждому элементу списка.
Эта функция является отличным примером одного из основных приемов работы в Haskell — паттерны. Map имеющая на входе параметры вида а f [] (функция и пустой список) возвратит пустой список. В остальных случаях f применится к первому элементу списка, получившийся элемент добавится (двоеточие) к списку, образованному путем применения функции map к хвосту списка.
Одно из главных достоинств Haskell — если вы сформулировали функцию на математическом языке, запрограммировать ее, как правило, дело нескольких минут.
А, вот, еще одно чудо: функции head и tail, ну, просто загляденье!
Думаю, тут даже объяснять нечего. Нижнее подчеркивание в паттернах Haskell расшифровывается как «все что угодно».
Неужели, существуют люди, которым это не нравится?
А вот функция length.
А как в прелюдии определен класс Eq? Вы будете смеяться!
Правда головокружительная красота?
Можно было бы привети много примеров кода, но зачем портить вам удовольствие?
Всем новичкам, всем кто хочет полюбить Haskell один совет — читайте прелюдию. Я читаю и стараюсь писать как в прелюдии. Хотя бы стремлюсь. Читая прелюдию я понял философию Haskell и полюбил этот язык, чего всем вам желаю!
Простите, за сумбур, наверное я не писатель, я очень плохо изложил все то, что было нужно, но мне очень хотелось поделиться с вами частичкой любви к Haskell и этим маленьким, но очень полезым советом. Читайте прелюдию!
Почему нельзя просто взять и пересесть на 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 и этим маленьким, но очень полезым советом. Читайте прелюдию!