Reducing the need for CPP (was: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`)
Jan-Willem Maessen
jmaessen at alum.mit.edu
Tue Oct 6 12:25:34 UTC 2015
On Tue, Oct 6, 2015 at 4:44 AM, Ben Gamari <ben at smart-cactus.org> wrote:
> Sven Panne <svenpanne at gmail.com> writes:
>
> > 2015-10-05 17:09 GMT+02:00 Gershom B <gershomb at gmail.com>:
> >
> >> On October 5, 2015 at 10:59:35 AM, Bryan O'Sullivan (bos at serpentine.com
> )
> >> wrote:
> >> [...] As for libraries, it has been pointed out, I believe, that without
> >> CPP one can write instances compatible with AMP, and also with AMP +
> MRP.
> >> One can also write code, sans CPP, compatible with pre- and post- AMP.
> [...]
> >>
> >
> > Nope, at least not if you care about -Wall: If you take e.g. (<$>) which
> is
> > now part of the Prelude, you can't simply import some compatibility
> module,
> > because GHC might tell you (rightfully) that that import is redundant,
> > because (<$>) is already visible through the Prelude. So you'll have to
> use
> > CPP to avoid that import on base >= 4.8, be it from it Data.Functor,
> > Control.Applicative or some compat-* module. And you'll have to use CPP
> in
> > each and every module using <$> then, unless I miss something obvious.
> > AFAICT all transitioning guides ignore -Wall and friends...
> >
> This is a fair point that comes up fairly often. The fact that CPP is
> required to silence redundant import warnings is quite unfortunate.
> Others languages have better stories in this area. One example is Rust,
> which has a quite flexible `#[allow(...)]` pragma which can be used to
> acknowledge and silence a wide variety of warnings and lints [1].
>
> I can think of a few ways (some better than others) how we might
> introduce a similar idea for import redundancy checks in Haskell,
>
> 1. Attach a `{-# ALLOW redundant_import #-}` pragma to a definition,
>
> -- in Control.Applicative
> {-# ALLOW redundant_import (<$>) #-}
> (<$>) :: (a -> b) -> f a -> f b
> (<$>) = fmap
>
> asking the compiler to pretend that any import of the symbol did not
> exist when looking for redundant imports. This would allow library
> authors to appropriately mark definitions when they are moved,
> saving downstream users from having to make any change whatsoever.
>
> 2. Or alternatively we could make this a idea a bit more precise,
>
> -- in Control.Applicative
> {-# ALLOW redundant_import Prelude.(<$>) #-}
> (<$>) :: (a -> b) -> f a -> f b
> (<$>) = fmap
>
> Which would ignore imports of `Control.Applicative.(<$>)` only if
> `Prelude.(<$>)` were also in scope.
>
One obvious solution I haven't seen mentioned is the ability to add
nonexistent identifier to a hiding clause (these identifiers might
presumably exist in some other version of the import):
import Prelude hiding ((<$>))
I can see the argument for marking such imports with a pragma, though it
gets a bit ugly.
-Jan-Willem Maessen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/libraries/attachments/20151006/c4319a11/attachment.html>
More information about the Libraries
mailing list