Действительно ли возможно использовать расширение CPP на коде Haskell, который содержит многострочные строковые литералы? Есть ли другие методы условной компиляции для Haskell?
Например, давайте возьмем этот код:
-- If the next line is uncommented, the program does not compile.
-- {-# LANGUAGE CPP #-}
msg = "Hello\
\ Wor\
\ld!"
main = putStrLn msg
Если я некомментирую {-# LANGUAGE CPP #-}
, затем GHC опровергает этот код с лексической ошибкой:
[1 of 1] Compiling Main ( cpp-multiline.hs, cpp-multiline.o )
cpp-multiline.hs:4:17:
lexical error in string/character literal at character 'o'
Используя GHC 6.12.1, cpphs доступен.
Я подтверждаю что с помощью cpphs.compat обертку и -pgmP cpphs.compat
опция помогает, но я хотел бы иметь решение, которое не зависит от пользовательских сценариев оболочки. -pgmP cpphs
не работает.
P.S. Я должен использовать другой код для GHC <6.12 и GHC> = 6.12, действительно ли это возможно без препроцессора?
UPD. В дополнение к принятому ответу Ganesh я также нашел, что другое обходное решение должно поместить все условные объявления в отдельный модуль с {-# LANGUAGE CPP #-}
и таким образом избегайте CPP в модулях с многострочными строками.
cpphs теперь имеет сам вариант --cpp, который, я думаю, делает скрипт compat ненужным: см. запись cpphs 1.3 в http://haskell.org/cpphs/
Я думаю, что вам нужно будет передать -optP --cpp
в GHC (а также -pgmP cpphs
), чтобы включить такое поведение.
Похоже, руководство пользователя GHC решает эту проблему: Раздел 4.10.3.1 читает
Небольшое предупреждение: -cpp не подходит для «пробелов в строках». Другими словами, такие строки следующим образом:
strmod = "\
\ p \
\ "
не работают с -cpp; / usr / bin / cpp исключает пары обратной косой черты и новой строки.
Однако, похоже, что если вы добавите пробел в конец строки, то cpp (по крайней мере, GNU cpp и, возможно, другие cpps) оставит только пары обратной косой черты и пробела, и разрыв строки будет работать должным образом.