views:

197

answers:

2

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.

+2  A: 

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.

Reid Barton
Thank you. I tried to add trailing spaces after \, but cpp just reports a warning `backslash and newline separated by space`, and the code still does not compile. Using GNU cpp 4.4.3.
jetxee
+2  A: 

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.

Ganesh Sittampalam
Thanks. With `optP --cpp` it works.
jetxee