Mark Needham

Thoughts on Software Development

Haskell: Using qualified imports to avoid polluting the namespace

with one comment

In most of the Haskell code I’ve read any functions from other modules have been imported directly into the namespace and I reached the stage where I had this list of imports in a file:

import System.IO
import Data.List.Split
import Data.Char
import Data.Bits
import Control.Monad 
import Data.Map 
import Data.Set 
import Data.List 
import Data.Maybe

This becomes a problem when you want to use a function which is defined in multiple modules such as filter:

clustering.hs:53:43:
    Ambiguous occurrence `filter'
    It could refer to either `Data.List.filter',
                             imported from `Data.List' at clustering.hs:11:1-16
                             (and originally defined in `GHC.List')
                          or `Data.Set.filter',
                             imported from `Data.Set' at clustering.hs:10:1-16
                          or `Data.Map.filter',
                             imported from `Data.Map' at clustering.hs:9:1-16

One way to solve this is to change occurrences of filter to Data.List.filter but it’s a bit long winded and in this case there is a function in the Prelude package which is available without us importing anything.

Unfortunately we’d have to use the prefix Prelude to refer to it since all the other versions of the function have made it ambiguous.

We still want to use some of the functions in those other modules though so we can do a qualified import which will make the functions available to us but only if we refer to them by their full name. It won’t import them into our namespace.

For example to initialise a map we’d do this:

> import qualified Data.Map
> Data.Map.assocs $ Data.Map.fromList [(1,2), (3,7)]
[(1,2),(3,7)]

That’s a bit long winded though so we can rename imports with a shorter name to make our life a bit easier:

import System.IO
import Data.List.Split
import Data.Char
import Data.Bits
import qualified Control.Monad as Monad
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Data.List as List
import qualified Data.Maybe as Maybe

We can then use functions in those packages like so:

> Maybe.maybeToList (Just 3)
[3]

For this particular function I haven’t come across any with the same name so we might want to import that one into our namespace but require the use of the Maybe prefix for any other functions:

import qualified Data.Maybe as Maybe
import Data.Maybe (maybeToList)
> maybeToList (Just 3)
[3]

There’s a wiki entry I came across which explains Haskell modules this in a bit more detail and is worth a read.

Written by Mark Needham

December 30th, 2012 at 11:16 pm

Posted in Haskell

Tagged with

  • http://franklinchen.com/ Franklin Chen

    For myself, I’ve simply come to always import qualified, with an alias. That way, I can easily determine where something is coming from.