<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Oct 6, 2015 at 4:44 AM, Ben Gamari <span dir="ltr"><<a href="mailto:ben@smart-cactus.org" target="_blank">ben@smart-cactus.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Sven Panne <<a href="mailto:svenpanne@gmail.com">svenpanne@gmail.com</a>> writes:<br>
<br>
> 2015-10-05 17:09 GMT+02:00 Gershom B <<a href="mailto:gershomb@gmail.com">gershomb@gmail.com</a>>:<br>
><br>
>> On October 5, 2015 at 10:59:35 AM, Bryan O'Sullivan (<a href="mailto:bos@serpentine.com">bos@serpentine.com</a>)<br>
>> wrote:<br>
>> [...] As for libraries, it has been pointed out, I believe, that without<br>
>> CPP one can write instances compatible with AMP, and also with AMP + MRP.<br>
>> One can also write code, sans CPP, compatible with pre- and post- AMP. [...]<br>
>><br>
><br>
> Nope, at least not if you care about -Wall: If you take e.g. (<$>) which is<br>
> now part of the Prelude, you can't simply import some compatibility module,<br>
> because GHC might tell you (rightfully) that that import is redundant,<br>
> because (<$>) is already visible through the Prelude. So you'll have to use<br>
> CPP to avoid that import on base >= 4.8, be it from it Data.Functor,<br>
> Control.Applicative or some compat-* module. And you'll have to use CPP in<br>
> each and every module using <$> then, unless I miss something obvious.<br>
> AFAICT all transitioning guides ignore -Wall and friends...<br>
><br>
This is a fair point that comes up fairly often. The fact that CPP is<br>
required to silence redundant import warnings is quite unfortunate.<br>
Others languages have better stories in this area. One example is Rust,<br>
which has a quite flexible `#[allow(...)]` pragma which can be used to<br>
acknowledge and silence a wide variety of warnings and lints [1].<br>
<br>
I can think of a few ways (some better than others) how we might<br>
introduce a similar idea for import redundancy checks in Haskell,<br>
<br>
 1. Attach a `{-# ALLOW redundant_import #-}` pragma to a definition,<br>
<br>
        -- in Control.Applicative<br>
        {-# ALLOW redundant_import (<$>) #-}<br>
        (<$>) :: (a -> b) -> f a -> f b<br>
        (<$>) = fmap<br>
<br>
    asking the compiler to pretend that any import of the symbol did not<br>
    exist when looking for redundant imports. This would allow library<br>
    authors to appropriately mark definitions when they are moved,<br>
    saving downstream users from having to make any change whatsoever.<br>
<br>
 2. Or alternatively we could make this a idea a bit more precise,<br>
<br>
        -- in Control.Applicative<br>
        {-# ALLOW redundant_import Prelude.(<$>) #-}<br>
        (<$>) :: (a -> b) -> f a -> f b<br>
        (<$>) = fmap<br>
<br>
    Which would ignore imports of `Control.Applicative.(<$>)` only if<br>
    `Prelude.(<$>)` were also in scope.<br></blockquote><div><br></div><div>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):</div><div><br></div><div>import Prelude hiding ((<$>))</div><div><br></div><div>I can see the argument for marking such imports with a pragma, though it gets a bit ugly.</div><div><br></div><div>-Jan-Willem Maessen</div></div></div></div>