Is it possible to use CPP extension on Haskell code which contains multiline string literals? Are there other conditional compilation techniques for Haskell?
For example, let's take this code:
-- If the next line is uncommented, the program does not compile.
-- {-# LANGUAGE CPP #-}
msg = "Hello\
\ Wor\
\ld!"
main = putStrLn msg
If I uncomment {-# LANGUAGE CPP #-}
, then GHC refutes this code with a lexical error:
[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'
Using GHC 6.12.1, cpphs is available.
I confirm that using cpphs.compat wrapper and -pgmP cpphs.compat
option helps, but I'd like to have a solution which does not depend on custom shell scripts. -pgmP cpphs
does not work.
P.S. I need to use different code for GHC < 6.12 and GHC >= 6.12, is it possible without preprocessor?
UPD. In addition to the accepted answer of Ganesh, I also found that another workaround is to put all conditional declarations in a separate module with {-# LANGUAGE CPP #-}
and thus avoid CPP in the modules with multiline strings.
cpphs now has a --cpp option itself, which I think makes the compat script unnecessary: see the cpphs 1.3 entry at http://haskell.org/cpphs/
I think you'd need to pass -optP --cpp
to GHC (as well as -pgmP cpphs
) to enable this behaviour.
It seems the GHC user manual addresses this: Section 4.10.3.1 reads
A small word of warning: -cpp is not friendly to “string gaps”.. In other words, strings such as the following:
strmod = "\
\ p \
\ "
don't work with -cpp; /usr/bin/cpp elides the backslash-newline pairs.
However, it appears that if you add a space at the end of the line, then cpp (at least GNU cpp and possibly other cpps) leaves the backslash-space pairs alone and the string gap works as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With