Search code examples
haskellbackwards-compatibilitycabal

How to enable Safe Haskell for a module in a backwards compatible way


Suppose you have a module that you know is safe.

You want to mark it as Safe Haskell with something like {-# LANGUAGE Safe #-} in the module itself or with something like Extensions: Safe in the cabal file. Unfortunately, doing either of these breaks backwards compatibility (i.e. the module will not build on GHC < 7.2).

If the entire library is Safe, you can just wrap the extensions directive in the cabal file like this:

if impl(ghc >= 7.2)
  Extensions: Safe

But that only works for the entire library.

How do you mark a single module as Safe Haskell in a backwards compatible way?


Solution

  • If you don't need to support GHC versions older than 6.12 (6.12.3 is the oldest I have tested the construct with¹), you can do it with the preprocessor,

    {-# LANGUAGE CPP #-}
    #if __GLASGOW_HASKELL__ >= 702
    {-# LANGUAGE Safe #-}
    #endif
    

    Alternatively, you can use a flag in the .cabal file to select the source file which to include.

    ¹ For ghc-6.12, you must have all {-# LANGUAGE #-} pragmas not guarded by the #if in one group before the #if, since 7.0, they may also appear after the #if.