Расширение 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 в модулях с многострочными строками.


person sastanin    schedule 30.03.2010    source источник
comment
Почему бы не использовать "Hello" ++ " Wor" ++ "ld!"?   -  person kennytm    schedule 31.03.2010
comment
Потому что "Hello\ whitespace+ \ World!" — это Haskell 98. Потому что есть код, который его использует. Потому что " ++ " занимает больше места (и мне не нравится код, превышающий 80 столбцов). И, наконец, я хотел бы написать патч без перепаковки и переформатирования каждой многострочной строки в проекте.   -  person sastanin    schedule 31.03.2010


Ответы (2)


cpphs теперь имеет сам параметр --cpp, который, я думаю, делает сценарий совместимости ненужным: см. запись cpphs 1.3 по адресу http://haskell.org/cpphs/

Я думаю, вам нужно передать -optP --cpp в GHC (а также -pgmP cpphs), чтобы включить это поведение.

person GS - Apologise to Monica    schedule 31.03.2010

Кажется, руководство пользователя GHC решает эту проблему: Раздел 4.10.3.1 гласит:

Небольшое предупреждение: -cpp не подходит для «пропусков строк». Другими словами, строк, таких как следующие:

strmod = "\
\ p \
\ "

не работать с -cpp; /usr/bin/cpp исключает пары обратная косая черта-новая строка.

Однако оказывается, что если вы добавите пробел в конце строки, то cpp (по крайней мере, GNU cpp и, возможно, другие cpps) оставит пары «обратная косая черта-пробел» в покое, и разрыв строки будет работать, как и ожидалось.

person Reid Barton    schedule 31.03.2010
comment
Спасибо. Я пытался добавить пробелы после \, но cpp просто выдает предупреждение backslash and newline separated by space, а код все равно не компилируется. Использование GNU cpp 4.4.3. - person sastanin; 31.03.2010