
I've noticed an annoying (anti)pattern when using modules that collide with other modules (esp with the prelude). I find this is most common with modules conflicting with Data.List or System.IO. I'm fairly new to Haskell (did a little last January with XMonad and Just now getting back into it) so maybe there is a better way to handle this. Example: import Data.Foldable (minimum, minimumBy, maximum, maximumBy) import Data.List hiding (minimum, minimumBy, maximum, maximumBy) import Prelude hiding (minimum, maximum) import System.IO.UTF8 (putStrLn, hPutStrLn) import System.IO hiding (putStrLn, hPutStrLn) import Prelude hiding (putStrLn) As you can see this can be quite annoying and is a disincentive to use improved or more general tools. Especially worrisome is that it is not obvious what you must hide from the Prelude. If you try to hide hPutStrLn or minimumBy you get an error. I found this led to a lot of trial and error (read: guess and check). I have a few ideas on how to solve this.The first two are using current syntax and simply doing what the programmer really meant. The third one is adding new syntax to allow a programmer to specify what they mean. All three should be able to work either together or separately. 1) Transitive Hiding If you hide something when importing a module it automatically hides identical imports. I cant think of a situation where this isn't what the user would want. This also seems easy to implement because the compiler already must know which functions are identical when checking for ambiguities. 2) Explicit Import Lists Take Precedence Any ambiguity should be resolved in favor of the module that has the name explicitly in its import list. An additional advantage here is that it offers some protection against a program breaking if a function is added to a module. This can be considered an extension of the current ImportShadowing (http://hackage.haskell.org/trac/haskell-prime/wiki/ImportShadowing) proposal if the current module is thought of as imported with everything explicit. 3) Import A Shadowing B This actually adds a new import style which I think is the best solution: import System.IO.UTF8 shadowing System.IO import Data.Foldable shadowing Data.List In each case all functions in A would shadow any function in B. I think this should behave like Transitive Hide where the identical Prelude functions would also be shadowed. A major advantage here is that it allows drop-in replacements for the standard libs to be easily used. A few things I could go either way on with this: 3.1) if minimum was explicitly imported from Data.List do we use it, Foldable.minimum, or do we error out? 3.2) if a module reexports Data.Foldable should it also reexport the shadowing? I could see this being useful on a big project where you import a module that reexports several modules shadowing the Prelude to create a specialized standard lib. 3.3) should there be a shadowing all? I may take a peek at GHC this weekend to see how easy it would be to add any of these as optional extensions. ~Mathias Stearn