Работа с конфигурационными файлами в Haskell

Ни одно достаточно крупное приложение не обходится без конфигурационных файлов. Сегодня мы познакомимся с пакетом configurator, который позволяет не только банально парсить конфиги в Haskell, но и делать другие интересные вещи. Например, узнавать об изменении конфигов и автоматически перечитывать их. Автором пакета является широко известный в узких кругах Bryan O’Sullivan.

Создадим у себя в домашнем каталоге простой конфиг с именем test.conf:

Как видите, синтаксис конфига прост и понятен. Также в конфиге можно импортировать другие конфиги:

Основные функции для работы с конфигурационными файлами следующие:

Создаем новый пустой конфиг.

Читаем конфигурационные файлы с диска. Тип Worth определяется примерно как data Worth a = Required a | Optional a.

Получение части конфига.

Перечитываем конфиги. При этом конфиги, полученные с помощью функции subconfig, также обновляются.

Чтение параметра из конфига.

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

Аналогично lookup, только в случае отсутствия параметра вместо того, чтобы вернуть Nothing, будет брошено исключение.

Вспомогательная функция для вывода конфига.

Преобразуем конфиг в простой HashMap. Удобно, например, для последующей передачи этого HashMap в чистые функции.

Теперь дружно скажем cabal install configurator и запустим ghci:

Загрузим наш конфиг:

Выведем его на экран:

Получим имя пользователя:

Попробуем поработать с сабконфигом:

… и использовать значения по умолчанию:

Совсем не сложно, правда?

Теперь попробуем разобраться с автоматическим обновлением конфигов. Типы и функции, которые нам понадобятся, следующие:

Этот тип определяет, как часто следует перечитывать конфиг и что делать в случае возникновения ошибки.

Возвращает значение по умолчанию типа AutoConfig. Интервал равен одной секунде, ошибки игнорируются.

Создает автоматически обновляемый конфиг.

Посмотрим на все это хозяйство в действии. Говорим:

Открываем конфиг, заменяем имя пользователя на «guest», снова говорим:

Кажется, работает! Ну, почти. На момент написания этих строк в configuratorбыло несколько неисправленных багов. Например, если использовать в пути к конфигу переменную $(HOME), он не будет обновляться. Ознакомиться со списком известных багов можно здесь.

Также configurator позволяет подписаться на обновления определенных частей конфига.

Возвращает шаблон для подписки на определенную часть конфига.

Создает шаблон для подписки на один конкретный параметр.

Тип функции, вызываемой при внесении изменений в конфиге.

Подписаться на изменения.

Проверяем:

Открываем конфиг и дописываем в него строчку:

В ghci видим:

Вот такой занятный пакет этот configurator. А чем вы парсите конфиги в Haskell?