[Haskell-cafe] Design your modules for qualified import

Andrew Coppin andrewcoppin at btinternet.com
Fri Jun 6 14:35:00 EDT 2008


Johan Tibell wrote:
> * Why is this practice common in Haskell
>
> Here are some guesses:
>
> 1. It's common in papers.

Maybe.
> 2. It's the default.
>   

Probably not.

> 3. Lack of common interfaces.
>   

Yes.

It's really quite frustrating that it is 100% impossible to write a 
single function that will process lists, arrays, sets, maps, byte 
strings, etc. You have to write several different versions. OK, so some 
functions really don't make sense for a set because it's unordered, and 
some functions don't make sense for a map, and so forth. But for 
example, if I write some complicated algorithm that uses a list to store 
data and I change that to a set instead, I now have to wade through the 
function changing every operation from a list-op into a set-op. It's 
really very annoying!

The problem - as I'm sure everybody is well aware - is that it's rather 
hard to come up with a type system formulation that works even though 
lists and arrays can store everything, unboxed arrays can only store 
types X, Y and Z, sets and maps require ordered data, byte strings only 
store bytes, and so on and so forth.

> 4. Haskell is a very expressive language. You can often write a whole
> function definition on one line! Adding those module qualifications
> makes your code slightly longer and it might just break your beautiful
> one liner into two lines.
>   

5. Writing "Hello" Prelude.++ "World" is just ugly. ;-)

In addition, I feel I should point out that only *very* recently did I 
discover that it is in fact possible to import a module qualified and 
still be able to refer to it easily. What do I mean by that? Well, 
suppose I do

  import Text.ParserCombinators.Parsec

I do *not* want to have to write "Text.ParserCombinators.Parsec.runParser"!!

Until very recently, it was not at all clear to me that there is 
actually a very simple solution to this problem:

  import Text.ParserCombinators.Parsec as P

Now I only have to write "P.runPaser", which is much shorter.

This fact probably needs to be mentioned more loudly - I'm sure I'm not 
the only person to have overlooked it...



More information about the Haskell-Cafe mailing list