Расширьте возможности своей IDE с помощью отладки, автодополнения и других функций Haskell.

Недавно я начал изучать Haskell. Первое, что вам нужно сделать при освоении нового языка, — это настроить среду разработки. Мне нравится VS Code и я работаю в основном в нем. Поэтому у меня не было сомнений, какой редактор я буду использовать во время обучения.

Первым делом я быстро поискал статьи на Medium, которые помогли бы мне настроить редактор. Настройка Haskell в VS Code со стеком и движком IDE Мэтью Дойга — хорошее место для начала, но оно немного устарело. Поэтому я решил написать нечто подобное, но с более актуальной информацией.

Еще один момент, который я хочу отметить заранее, я использую macOS, поэтому сочетания клавиш и другие вещи были протестированы на указанной ОС. Он может работать по-разному на вашем ноутбуке или ПК.

Итак, основная проблема заключается в том, что по умолчанию VS Code не показывает никаких признаков поддержки Haskell. Тем не менее, проблему можно легко устранить, выполнив несколько простых шагов.

Хорошо, тогда давайте начнем отсюда.

Шаг 0. Получите свой код VS

Перейдите на главную страницу VS Code и загрузите установщик для выбранной вами ОС.

С этого момента я буду предполагать, что у вас установлен VS Code, поэтому давайте перейдем к его настройке :)

Шаг 1. GHКупить это

GHCup — это инсталлятор для языка общего назначения Haskell.

GHCup — это самый простой способ установить все, что вам нужно для запуска вашего пути к Haskell: компилятор, системы упаковки и распространения и так далее. Звучит здорово, стоит ли нам попробовать? Конечно.

Откройте терминал либо внутри VS Code, либо как отдельную программу, и выполните внутри него следующую команду:

$ curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh

Программа спросит вас, хотите ли вы добавить все необходимое в ваш .zshrc или другие файлы конфигурации оболочки. Я предпочитаю вариант добавления, хотя вы можете выбрать сами:

После этого GHCup предложит установить Haskell Language Server и стек. Эти два пункта обязательно пригодятся позже, поэтому ответ Да:

Как только мы выбрали все нужные нам параметры, должен начаться процесс установки:

Нажмите Enter, чтобы продолжить, и дождитесь завершения всего процесса. Просто совет: выпейте чашку чая, так как это может занять некоторое время.

Отлично, мы готовы. Теперь давайте настроим наш VS Code. Для этого нам нужно создать новый проект. Для этой цели я предпочитаю стек. Поэтому откройте окно терминала и введите следующие команды:

$ stack new vscode-haskell-config
$ cd vscode-haskell-config
$ stack setup

Шаг 2. Подсветка синтаксиса

Первое, что мы хотим получить от текстового редактора или IDE, — раскрашенный код. Этого легко добиться, установив специальное расширение:

Кроме того, может потребоваться перезагрузка редактора, так что будьте внимательны. После установки app/Main.hs, которое вы видели в начале, должно выглядеть примерно так, в зависимости от вашей цветовой схемы:

Это определенно улучшение, но до функциональности IDE еще далеко. В предыдущем разделе мы добавили Haskell Language Server (HLS), и было бы неплохо включить его функциональность в VS Code.

Шаг 3. Накачайте VS Code Up

Процесс настройки HLS действительно сложен, но это не так. Есть два простых шага, которые вам нужно выполнить, чтобы заставить его работать:

̶̶̶1̶̶̶.̶̶̶ ̶̶̶I̶̶̶n̶̶̶s̶̶̶t̶̶̶a̶̶̶l̶̶̶l̶̶̶ ̶̶̶H̶̶̶a̶̶̶s̶̶̶k̶̶̶e̶̶̶l̶̶̶l̶̶̶ ̶̶̶S̶̶̶y̶̶̶n̶̶̶t̶̶̶a̶̶̶x̶̶̶ ̶̶̶H̶̶̶i̶̶̶g̶̶̶h̶̶̶l̶̶̶i̶̶̶g̶̶̶h̶̶̶t̶̶̶i̶̶̶n̶̶̶g̶̶̶ ̶̶̶e̶̶̶x̶̶̶t̶̶̶e̶̶̶n̶̶̶s̶̶̶i̶̶̶o̶̶̶n̶̶̶.̶̶̶ ̶̶̶W̶̶̶a̶̶̶i̶̶̶t̶̶̶ ̶̶̶a̶̶̶ ̶̶̶s̶̶̶e̶̶̶c̶̶̶…̶̶̶ ̶̶̶W̶̶̶e̶̶̶ ̶̶̶f̶̶̶i̶̶̶n̶̶̶i̶̶̶s̶̶̶h̶̶̶e̶̶̶d̶̶̶ ̶̶̶i̶̶̶t̶̶̶ ̶̶̶j̶̶̶u̶̶̶s̶̶̶t̶̶̶ ̶̶̶a̶̶̶ ̶̶̶f̶̶̶e̶̶̶w̶̶̶ ̶̶̶m̶̶̶i̶̶̶n̶̶̶u̶̶̶t̶̶̶e̶̶̶s̶̶̶ ̶̶̶a̶̶̶g̶̶̶o̶̶̶…̶̶̶ ̶̶̶C̶̶̶o̶̶̶o̶̶̶l̶̶̶,̶̶̶ ̶̶̶h̶̶̶u̶̶̶h̶̶̶?̶̶̶ ̶̶̶T̶̶̶h̶̶̶u̶̶̶s̶̶̶,̶̶̶ ̶̶̶t̶̶̶h̶̶̶e̶̶̶ ̶̶̶s̶̶̶i̶̶̶n̶̶̶g̶̶̶l̶̶̶e̶̶̶ ̶̶̶s̶̶̶t̶̶̶e̶̶̶p̶̶̶ ̶̶̶l̶̶̶e̶̶̶f̶̶̶t̶̶̶.̶̶̶

1. Установите расширение поддержки HLS:

Нажмите кнопку "Установить" и подождите, пока редактор сделает все остальное. Ну вот. После установки наша будущая IDE показывает красную волнистую линию в нашем app/Main.hs:

Чтобы решить эту проблему, нам нужно находиться в каталоге проекта в нашем терминале и ввести следующие команды:

$ stack clean --full
$ stack build

Теперь все должно быть в цвете:

HLS — чрезвычайно полезный инструмент. Он предоставляет нашему коду VS (и нам, конечно) следующее:

  • введите информацию и документацию при наведении

  • автодополнение

  • рекомендации по рефакторингу и стилю кода от hlint

  • другие удобные функции, которые ожидаются от IDE

Любое форматирование кода?

Это хороший вопрос. На самом деле, HLS предоставляет вам эти возможности, хотя я не сказал вам об этом намеренно. Существует несколько поставщиков форматирования с именем по умолчанию Ormolu. Я настоятельно рекомендую вам попробовать их все и выбрать тот, который удовлетворит ваши потребности и вкус.

Тем не менее, лично я предпочитаю Бретани. Это моя статья, поэтому вам не повезло, если вы ожидаете увидеть здесь что-то другое :)

Таким образом, я покажу, как вы можете легко изменить поставщика форматирования на Brettany.

Для этого нажмите эту комбинацию на клавиатуре Cmd + , или нажмите Код -> Настройки -> Настройки:

Готовый? Отлично, идем дальше. Теперь введите "Haskell" в строке поиска настроек и найдите раздел "Formatting Provider", где должен быть выбран Ormolu:

Теперь давайте выберем другой вариант, например Бретани:

Хорошо, а что, если мы хотим убедиться, что это действительно работает, потому что мы не доверяем этим модным редакторам? Прежде всего, нам нужно добавить код, чтобы увидеть форматирование в действии.

Давайте откроем файл ./src/Lib.hs, так как мы поместим туда нашу новую функцию. Вы можете стереть все содержимое файла, не беспокойтесь.

Пожалуйста, перепечатайте пример с этими несоответствиями, так как мы отформатируем его автоматически.

Подождите секунду… Как мы все равно используем форматтер? Нажмите Opt + Shift + F, и Бриттани сделает всю тяжелую работу.

Пожалуйста, не волнуйтесь, если вы не понимаете, что происходит, смысл был в том, чтобы протестировать автоматическое форматирование. Вроде нормально работает :)

Отладка кода Haskell

Несмотря на представление о том, что если код на Haskell компилируется, он работает должным образом, возможности отладки могут оказаться полезными. К сожалению, в HLS нет отладчика (по крайней мере, по состоянию на ноябрь 2021 года).

К счастью, эта «слабость» легко устраняется установкой другого классного расширения.

Вы только что установили его? Это потрясающе! Мы почти готовы начать отладку. Перед фактическим запуском мы должны а) добавить тесты и б) настроить отладчик.

а) Добавление тестов

Если мы попытаемся запустить отладчик без каких-либо тестов, он выйдет с сообщением «Набор тестов еще не реализован».

Это именно то, что мы получаем от бега

$ stack test

Мы можем наблюдать эту строку в test/Spec.hs:

В порядке Хорошо. Кажется, нам просто нужно реализовать некоторые тесты. Звучит разумно.

Для этого мы будем использовать QuckCheck. Это потрясающая библиотека, позволяющая нам проводить тестирование на основе свойств. Мы напишем только один тест для функции pal, так как нам нужно протестировать отладчик, а не написать правильный набор тестов.

Прежде всего, давайте добавим QuickCheck в наш проект. Перейдите на package.yaml и в разделе tests найдите подраздел dependencies. Не стесняйтесь добавлять библиотеку в качестве зависимости:

Скучная часть почти закончена, мы собираемся погрузиться в удивительный мир тестирования на основе свойств. Пожалуйста, снова откройте файл ./test/Spec.hs. Важно решить в начале: что будет тестироваться? Поскольку у нас нет множества вариантов, просто импортируйте pal :)

import Lib (pal)

Следующим шагом будет добавление еще одного импорта, на этот раз QuickCheck. После этого ваш Spec.hs имеет следующее содержимое:

import Test.QuickCheck
import Lib (pal)

Давайте напишем наш первый тест свойства. Мы собираемся назвать его prop_reverseInvariant, который проверяет, что функция pal, примененная к перевернутому палиндрому, также должна возвращать True.

import Test.QuickCheck
import Lib (pal)
prop_reverseInvariant :: String -> Bool
prop_reverseInvariant text = pal text == pal (reverse text)

После некоторого форматирования с помощью Brittany содержимое файла будет следующим:

Примечание. Возможно, вы столкнулись со следующей проблемой:

Warning: Installation path /Users/<username>/.local/bin not found on the PATH environment variable.

Все, что вам нужно сделать, чтобы решить эту проблему, это добавить это в ваш .zshrc или другой файл конфигурации оболочки:

export PATH=$PATH:~/.local/bin

б) Настройка отладчика

Нажмите кнопку "Запустить и отладить" на боковой панели в VS Code:

Что дальше? Сначала нам нужно создать файл launch.json, чтобы настроить все, что связано с тем, «как IDE должна запускать наш отладчик?» Сделайте это, нажав «создать файл launch.json». Выберите haskell-debug-adapter в раскрывающемся списке:

Поздравляю, в корне проекта создана директория .vscode с соответствующей конфигурацией. Но… Мы заинтересованы в том, чтобы запустить отладчик, а не заниматься всеми этими скучными вещами. Пожалуйста, наберитесь терпения :)

Добавьте несколько строк в файл test/Spec.hs:

main :: IO ()
main = do
  quickCheck prop_reverseInvariant

Вставьте точку останова в строку 9 и запустите отладчик с параметром haskell(stack). Убедитесь, что это действительно останавливает выполнение, потому что в этом суть :)

Приятного знакомства с Haskell с настроенной IDE

В основном это когда мы говорим о настройке кода VS для Haskell. Теперь у вас есть вся подсветка синтаксиса и функциональность IDE, а также инструменты для отладки нашего кода.

В разработке могут быть и другие полезные вещи, такие как ghcid. Хотя он не имеет никакого отношения к VS Code, поэтому не стесняйтесь изучать эти инструменты самостоятельно :)

Чего же ты ждешь? Наслаждайтесь изучением Haskell и получайте удовольствие! :)

UPD. Я получил несколько отзывов о LinkedIn и Reddit, которые я считаю довольно полезными, но не хочу брать за это кредиты.

Вы можете найти интересные комментарии в теме r/haskell. Проверьте это.

Еще один момент, который я хотел добавить, был изложен Рамоном Сото Матиесеном (большое спасибо за это) в LinkedIn относительно флага -with-rtsopts=-N -qg GHC. Эта вставка может прояснить, почему вам может понадобиться это добавить.