#haskell #c-preprocessor #conditional-compilation
#haskell #c-препроцессор #условная компиляция
Вопрос:
Расширения CPP допускают условную компиляцию, например
{-# LANGUAGE CPP #-}
#ifdef DEBUG
-- some debug code
#endif
Конечно, это работает нормально, но это довольно неуклюже и неидиоматично. Неужели нет другого механизма для достижения условной компиляции?
(Конкретный случай, когда я действительно хотел бы его использовать, — это Text.Megaparsec.Функция Debug.dbg. Создаваемый им синтаксический анализ действительно полезен, но исходный код замусорен #ifdef
… #endif
шумом, что делает все это довольно нечитаемым. Функция-оболочка в верхней части удалит большую часть шума, но, тем не менее, мне интересно.)
Комментарии:
1. Я бы сказал, что CPP является распространенным способом достижения условной компиляции. Я бы также сказал, что CPP на данный момент является идиоматическим способом. Другим вариантом является шаблон Haskell, который в некоторых случаях может использоваться для этой цели, но я никогда не видел, чтобы он использовался как таковой.
2. Другим потенциальным вариантом было бы использовать Backpack . Поместите функцию отладки в сигнатуру модуля, затем напишите две внутренние библиотеки с реализациями: одна, которая не работает, другая, которая делегирует истинную функцию отладки.
Ответ №1:
Легкое решение — использовать CPP только один раз для определения логического значения, которое затем можно использовать в обычном коде Haskell:
#ifdef DEBUG
#define debug True
#else
#define debug False
#fi
или макрос, если вы даже не хотите, чтобы отладочный код проходил проверку типов.
Другой способ выполнить условную компиляцию без CPP — это изменить источник модулей на уровне пакета, хотя я не знаю ни одного реального примера этого.
Создайте два модуля с одинаковым именем debug/Debug.hs
и nodebug/Debug.hs
оба экспортируют, например, логическое debug :: Bool
значение .
В конфигурации пакета добавьте флаг для выбора между debug/
и nodebug/
.
flag debug
description: debug mode
default: False
manual: True
library
...
if flag(debug)
hs-source-dirs: debug
else
hs-source-dirs: nodebug
Теперь вы можете создать библиотеку с -f debug
помощью, чтобы включить отладку.