Подтвердить что ты не робот

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

4b9b3361

Ответ 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) оставит пары обратного слэша в пространстве, а разрыв в строке будет работать как ожидалось.