Где я могу узнать о #ifdef?
Я вижу, что это часто используется для обеспечения совместимости модулей с GHC и Hugs, но Google не помогает мне больше узнать об этом.
Что я могу установить внутри условного? Могу ли я сделать части модуля условными, какая версия "базы" используется?
EDIT 3/2017. Это отличный ресурс: https://guide.aelve.com/haskell/cpp-vww0qd72
Ответы
Ответ 1
В документации GHC есть раздел относящийся к предварительному процессору C, который документирует некоторые из предопределенных
макросы предварительного процессора.
В документации Cabal есть раздел относящийся к условной компиляции, в котором приведен пример, относящийся к base
. Если вы пишете переносной пакет, вы все равно должны использовать Cabal.
Ответ 2
В дополнение к очень полезным флагам, определенным GHC (OS, архитектурой и т.д.), при использовании кабала определены другие флаги и макросы.
Проверить версии пакета
Здесь используется crypto-api, который проверяет версию используемого пакета tagged
:
#if MIN_VERSION_tagged(0,2,0)
import Data.Proxy
#endif
Пользовательский CPP определяет на основе флагов Cabal
Вы можете определять символы CPP, зависящие от флагов cabal. Здесь (необязательно сложный) пример из pureMD5 (из файла .cabal):
if arch(i386) || arch(x86_64)
cpp-options: -DFastWordExtract
Внутри модуля .hs
вы можете использовать #ifdef
, например:
#ifdef FastWordExtract
getNthWord n b = inlinePerformIO (unsafeUseAsCString b (flip peekElemOff n . castPtr))
#else
... other code ...
#endif
Для получения дополнительной информации вы можете увидеть руководство пользователя Cabal. Эта страница содержит информацию об условной компиляции, которую вы, вероятно, ищете.
Ответ 3
#ifdef
и друзья используются препроцессором C (CPP). Они обеспечивают способ компиляции кода условно. Вы можете включить использование CPP, добавив прагма {-# LANGUAGE CPP #-}
поверх файла.
Многие программы, относящиеся к коду Haskell, устанавливают некоторые макросы для препроцессора (например, GHC устанавливает __GLASGOW_HASKELL__
в версию GHC), поэтому можно условно скомпилировать код, например, для использования различных собственных библиотек для Hugs и GHC.
Ответ 4
Если вы запустите свой компилятор Haskell с опцией -cpp
, он сначала предварительно обработает исходные файлы с помощью CPP (C Pre Processor).
Взгляните на раздел 4.11.3. Опции, влияющие на предварительный процессор C здесь.