learn haskell
24 subscribers
2 photos
2 links
изучение языка haskell
Download Telegram
Channel created
Channel photo updated
Haskell — это чисто функциональный, статически типизированный язык программирования, названный в честь логика Хаскелла Карри.
Он был разработан в 1980-х годах группой исследователей, чтобы создать основанный на исследовании язык, объединяющий лучшие идеи функционального программирования.
Язык популярен как в академической среде, так и в промышленной разработке (в основном в финансах, криптографии, компиляторах и системах с высокой надёжностью).

Основные черты Haskell:
1. Чисто функциональный
Функции в Haskell не имеют побочных эффектов (например, изменения глобальных переменных, ввода-вывода и т.д.).
2. Ленивые вычисления
Выражения вычисляются только тогда, когда это необходимо.
3. Статическая типизация
Типы проверяются на этапе компиляции.
4. Полиморфизм и типовые классы
Поддержка алгебраических типов данных (ADT) и типовых классов (class, instance), похожих на интерфейсы в других языках.
5. Монады
Монады — это мощный инструмент для работы с побочными эффектами, например, вводом-выводом (IO), обработкой ошибок (Maybe, Either), состоянием (State).

Плюсы Haskell
- Высокий уровень абстракции.
- Безопасность типов.
- Лёгкость тестирования и рефакторинга.
- Мощная система типов.
- Отличен для написания сложной логики и прототипов.

Минусы Haskell
- Крутая кривая обучения.
- Меньше библиотек и ресурсов по сравнению с популярными языками.
- Меньше производительности в некоторых задачах.
- Сложности с отладкой ленивых вычислений.
ghcup
Это инструмент управления Haskell, расшифровывается как GHC Up (Glasgow Haskell Compiler Up).
Он предназначен для установки, обновления и управления различными версиями компилятора GHC, а также других инструментов Haskell, таких как:
- GHC (Glasgow Haskell Compiler) — основной компилятор Haskell.
- Cabal (Haskell Package Manager) — менеджер пакетов.
- Stack — альтернативный инструмент сборки и управления зависимостями.
- HLS (Haskell Language Server) — сервер для поддержки языка в редакторах.

Зачем нужен ghcup?
Когда вы работаете с Haskell, у вас может быть несколько проектов, требующих разных версий GHC или других инструментов. ghcup позволяет:
- Устанавливать несколько версий GHC параллельно.
- Переключаться между ними в зависимости от проекта.
- Устанавливать и обновлять HLS и другие инструменты.
- Управлять системой Haskell в удобном и централизованном виде.

Установка ghcup
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh

После установки ghcup автоматически настроит переменные окружения и предложит добавить пути в ~/.bashrc, ~/.zshrc и т.д.
Как создать простой проект

В каталоге проектов набираем (name это имя проекта)
stack new name


Для создания проекта можно использовать схему simple - она создаёт меньше файлов в проекте.
stack new name simple


Сборка
stack build


После этого внутри каталога .stack-work появиться исполняемый файл, его можно запустить так
stack exec name


Форматировать (отступы и всякое такое) файл
fourmolu -i Module.hs

Установить форматтер можно командой:
stack install fourmolu


Форматировать каталог
fourmolu -i src
Что такое функция?

В языке Haskell функция — это основная единица вычисления и центральный элемент языка. Это чистое, математическое отображение входных значений в выходные, без побочных эффектов, и с мощной поддержкой композиции, полиморфизма и каррирования.

Функции в Haskell следуют трём обязательным правилам:
1. все функции должны принимать аргументы,
2. все функции должны возвращать значение,
3. функция возвращает один и тот же результат для одного и того же набора аргументов (чистота, ссылочная прозрачность).

Функции в Haskell не могут иметь побочных эффектов (на самом деле могут, но это нужно специально указывать).

Функции в Haskell — это значения, как числа или строки. Их можно:
- Передавать как аргументы другим функциям.
- Возвращать из функций.
- Присваивать переменным.
- Хранить в структурах данных.

В Haskell все функции по умолчанию каррированы — то есть функция от нескольких аргументов на самом деле является функцией от одного аргумента, возвращающей другую функцию.

Примеры функций
Простая функция:
square :: Int -> Int
square x = x * x

Функция высшего порядка (принимает другую функцию):
applyTwice :: (a -> a) -> a -> a
applyTwice f x = f (f x)

Рекурсивная функция:
factorial :: Integer -> Integer
factorial 0 = 1
factorial n = n * factorial (n - 1)
Алонзо Чёрч (Alonzo Church, 14 июня 1903 — 11 августа 1995) — выдающийся американский математик и логик, один из основоположников теоретической информатики и математической логики. Оказал огромное влияние не только на математику и логику, но и на зарождение информатики как науки.

Лямбда-исчисление
В 1930-х годах Чёрч разработал лямбда-исчисление — формальную систему для описания функций и вычислений. Эта система стала фундаментом для функционального программирования и повлияла на развитие многих языков программирования, таких как Lisp, Haskell, ML и другие.

Тезис Чёрча — Тьюринга
Вместе с Аланом Тьюрингом он сформулировал тезис Чёрча — Тьюринга, утверждающий, что любая функция, которую можно "вычислить алгоритмически", может быть вычислена либо с помощью машины Тьюринга, либо в рамках лямбда-исчисления. Этот тезис лёг в основу теории вычислимости.

Теорема Чёрча о неразрешимости
В 1936 году он доказал, что проблема разрешения (Entscheidungsproblem) — задача определения истинности любого логического утверждения в рамках формальной системы — неразрешима. Это было сделано независимо и почти одновременно с Тьюрингом.

Логика и философия
Чёрч внёс значительный вклад в интенсиональную логику и разработал так называемую "теорию типов Чёрча", а также занимался философскими вопросами смысла и референции.
Как создать простой проект шаг за шагом

В каталоге проектов набираем
stack new firstpro simple


это создаст каталог шаблона простого проекта. Заглянем внутрь:
|- src
|- - Main.hs
|- CHANGELOG.md
|- LICENSE
|- README.md
|- Setup.hs
|- firstpro.cabal
|- stack.yaml

Нас интересует файл Main.hs - это отправная точка для работы нашего проекта.
Внутри там написан простой hello world
module Main (main) where

main :: IO ()
main = do
putStrLn "hello world"


Соберём ...
stack build

... и запустим его
stack exec firstpro


Далее в файле Main.hs можно добавлять свои функции, добавлять свои модули в проект, но это уже совсем другая история.
👍1
Haskell Playground

Что делать, если нет возможности или желания ставить haskell на комп, но нужно что-то попрогать? Для этого есть онлайн песочницы.
Для haskell это https://play.haskell.org/
Как и многие подобные платформы она позволяет выбрать версию компилятора и уровень оптимизации, посмотреть ассемблерный код и код, транслируемый в haskell core (это внутренний язык компилятора GHC).
Haskell Core

Это внутренний язык компилятора GHC (Glasgow Haskell Compiler) языка Haskell. Он представляет собой расширение системы полиморфного λ-исчисления высших порядков System Fω.
Core используется для трансляции кода на Haskell в промежуточное представление, которое упрощает анализ программ и оптимизацию.
Код на Haskell транслируется в Core во время компиляции. Это происходит с помощью дешугаринга (убираем синтаксический сахар) — перевода программы, которая использует многие конструкции языка, в программу, использующую только несколько.
Core имеет гораздо меньше синтаксических форм по сравнению с исходным языком Haskell.
Некоторые особенности Core:
- Привязки функций — всегда имеют одно имя переменной в левой части, преобразуются в лямбды.
- Многоаргументные функции — переводятся во вложенные лямбды, в Core все лямбды — одноаргументные.
- Полиморфные функции — в Core нужно указывать аргументы типов, в исходном Haskell — только аргументы значений.
- Конструкторы данных — например, при построении кортежа из трёх элементов в Core передаются шесть аргументов: сначала типы элементов, затем элементы.
Переменные

Математические аналогии в Haskell не заканчиваются на функциях. В Haskell не переменные, а объявления, или константные переменные, если брать аналогию из других языков.
Например, записать где-то
x = 3
...
x = 5

не получится, компилятор откажется такое компилировать.
Если рассматривать переменные, как естественный способ упрощения записи вычислений, то Haskell предлагает 2 варианта, которые можно комбинировать - блоки let и where:
calcChange :: Int -> Int -> Int
calcChange owed given =
let change = given - owed
in
if change > 0
then change
else 0

или
calcChange :: Int -> Int -> Int
calcChange owed given = if change > 0
then change
else 0
where change = given - owed

такая запись больше походит на определение математической формулы и привычнее для использования в академических задачах.
🔥1
GHCI

GHCi — это интерактивная среда (REPL — Read-Eval-Print Loop) для языка программирования Haskell, входящая в состав компилятора GHC (Glasgow Haskell Compiler).

Основные функции GHCi
- Выполнение Haskell-выражений в реальном времени;
- Можно вводить выражения, функции, определения и сразу видеть результат;
- Загрузка и тестирование модулей;
- Можно загрузить .hs-файлы (например, :load MyModule.hs) и работать с их содержимым;
- Отладка и инспекция типов. GHCi позволяет проверять типы выражений с помощью команды :type (сокращённо :t).

Когда GHCi особенно полезен
- изучение Haskell;
- быстрое прототипирование кода;
- тестирование функций без компиляции всего проекта.

Полезные команды
:load / :l - загрузить файл
:reload / :r - перезагрузить текущий файл
:type / :t - показать тип выражения
:info / :i - информация о функции, типе или классе типов
:help / :? - справка по командам
:quit / :q - выйти из GHCi
:set +t - После выполнения команды интерпретатор будет выводить на экран не только результат вычисления выражения, но и его тип.
:set +s - После выполнения команды интерпретатор будет выводить на экран не только результат вычисления выражения, но и статистику вычислений.

Пример использование GHCI
Запускаем интерпретатор командой
ghci

и далее пишем что хотим
ghci> let factorial 0 = 1; factorial n = n * factorial (n - 1)
ghci> factorial 5
120
ghci> :t factorial
factorial :: (Eq p, Num p) => p -> p