How to avoid CPP (Was: [Haskell-cafe] Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`)
Henning Thielemann
lemming at henning-thielemann.de
Sun Oct 18 18:49:58 UTC 2015
On Mon, 5 Oct 2015, Gregory Collins wrote:
> Um, no, it usually isn't anything like that. Here's a sampling of some of the things I've used CPP for in the past few
> years:
> * After GHC 7.4, when using a newtype in FFI imports you need to import the constructor, i.e. "import
> Foreign.C.Types(CInt(..))" --- afaik CPP is the only way to shut up warnings everywhere
I import them qualified and then define
type CInt = CTypes.CInt
sometimes.
> * defaultTimeLocale moved from System.Locale to Data.Time.Format in time-1.5 (no compat package for this, afaik)
I was advised to always import time-1.5.
> * one of many various changes to Typeable in the GHC 7.* series (deriving works better now, mkTyCon vs mkTyCon3, etc)
I have not used that. Like I have not used the ever changing Template
Haskell stuff.
> * Do I have to hide "catch" from Prelude, or not? It got moved, and "hiding" gives an error if the symbol you're trying
> to hide is missing. Time to break out the CPP (and curse myself for not just using the qualified import in the first
> place)
I think System.IO.Error.catchIOError maintains the old behaviour.
> * Do I get monoid functions from Prelude or from Data.Monoid? Same w/ Applicative, Foldable, Word. I don't know where
> anything is supposed to live anymore, or which sequence of imports will shut up spurious warnings on all four versions
> of GHC I support, so the lowest-friction fix is: break out the #ifdef spackle
I always import them from the most specific module. Where GHC-7.10 Prelude
causes conflicts I even started to import more basic Prelude stuff from
modules like Data.Bool, Data.Eq and friends. Horrible, but works without
CPP.
> * ==# and friends return Int# instead of Bool after GHC 7.8.1
I did not use it. I have also warned that the change might not be a good
idea since LLVM knows that its 'i1' type can only have the values 0 and 1
and it does not know that for 'i32' or 'i64'.
> * To use functions like "tryReadMVar", "unsafeShiftR", and "atomicModifyIORef'" that are in recent base versions but not
> older ones (this is a place where CPP use is actually justified)
I have not used them so far.
I have solved more complicated cases with conditional Hs-Source-Dirs:
http://wiki.haskell.org/Cabal/Developer-FAQ#Adapt_to_different_systems_without_CPP
It's cumbersome but so far I managed most transitions without CPP.
(Nonetheless, MRP would require the complicated Hs-Source-Dirs solution
for far too many packages.)
More information about the Libraries
mailing list