Расширение CPP и многострочные литералы в Haskell
Можно ли использовать расширение 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. В дополнение к принятому ответу Ганеша, я также обнаружил, что другим обходным путем является размещение всех условных объявлений в отдельном модуле с помощью {-# LANGUAGE CPP #-}
и, таким образом, исключение CPP в модулях с многострочными строками.
Ответы
Ответ 1
В cpphs теперь есть опция -cpp, которая, по-моему, делает необязательным compomp script: см. запись cpphs 1.3 на http://haskell.org/cpphs/
Я думаю, вам нужно передать -optP --cpp
в GHC (а также -pgmP cpphs
), чтобы включить это поведение.
Ответ 2
Кажется, руководство пользователя GHC обращается к этому: Раздел 4.10.3.1 читает
Небольшое предупреждение: -cpp не подходит для "пробелов в строке". Другими словами, строки, такие как:
strmod = "\
\ p \
\ "
не работают с -cpp;/usr/bin/cpp возвращает пары обратной косой черты.
Однако кажется, что если вы добавите пробел в конце строки, то cpp (по крайней мере, GNU cpp и, возможно, другие cpps) оставит пары обратного слэша в пространстве, а разрыв в строке будет работать как ожидалось.