Skip to content

Haskell Modules Guide — Module Declarations, Exports, and Import Control

DodaTech Updated 2026-06-28 2 min read

In this tutorial, you will learn about Haskell Modules Guide. We cover key concepts, practical examples, and best practices to help you master this topic.

Haskell modules group related definitions with explicit export lists controlling visibility, import statements with qualified and hiding modifiers, and hierarchical naming (Data.List, Data.Map) for namespace management in large projects.

Module Declaration

-- File: src/Geometry/Shapes.hs
module Geometry.Shapes
    ( Circle(..)
    , Rectangle(..)
    , area
    , circumference
    ) where

data Circle = Circle { radius :: Double }
data Rectangle = Rectangle { width :: Double, height :: Double }

area :: Circle -> Double
area (Circle r) = pi * r ^ 2

areaRect :: Rectangle -> Double  -- NOT exported
areaRect (Rectangle w h) = w * h

circumference :: Circle -> Double
circumference (Circle r) = 2 * pi * r

Importing Modules

-- Full import
import Data.List
import Data.Maybe

-- Qualified import
import qualified Data.Map as Map
import qualified Data.Set as Set

-- Selective import
import Data.List (sort, nub, intercalate)

-- Import everything except
import Data.List hiding (sort)

-- Re-export
module MyModule
    ( module Data.List
    , myFunction
    ) where

import Data.List

Submodules

-- File: src/Geometry/Circle.hs
module Geometry.Circle where

area :: Double -> Double -> Double
area r = pi * r ^ 2
-- File: src/Geometry.hs
module Geometry
    ( module Geometry.Circle
    , module Geometry.Rectangle
    ) where

import Geometry.Circle
import Geometry.Rectangle

Common Mistakes

1. Not using export lists

Without an export list, everything is exported. Always specify exports for library modules to hide internals.

2. Circular imports

Module A imports B, B imports A. This creates a compile error. Refactor shared code into a third module.

3. Name clashes

Two imported modules exporting the same name. Use qualified imports or import hiding to resolve.

Practice Questions

1. How do you export only specific functions? List them after the module declaration: module MyMod (func1, func2) where.

2. What does import qualified do? Imports require module prefix: qualified Data.Map as Map means Map.lookup, not lookup.

3. How do you avoid name clashes? Use qualified imports, hiding, or import only specific names from each module.

FAQ

{{< faq question="What is the default export behavior?" >}} If no export list is given, everything defined in the module is exported. Add an export list to control visibility.

{{< /faq >}}

{{< faq question="Can I re-export from another module?" >}} Yes, list module OtherModule in the export list. This is common for convenience modules that bundle related functionality.

{{< /faq >}}

{{< faq question="What is the module naming convention?" >}} Haskell modules use hierarchical dot notation matching directory structure: Data.Map is in Data/Map.hs. {{< /faq >}}

What's Next

Now learn about lazy evaluation in Haskell.

Topic Description Link
Lazy Evaluation Laziness and thunks {{< ref "17-lazy-evaluation" >}}
Error Handling Exception Handling {{< ref "18-error-handling" >}}

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro