-
Notifications
You must be signed in to change notification settings - Fork 4
📘 Haskell Tutorial: Understanding Modules and Imports Haskell
- 🧩 Introduction to Haskell Modules
- 📦 How Imports Work
- 🌳 Standard Haskell Module Hierarchy
- 🎯 Qualified Imports Explained
- 🧠 Using Aliases with
as - ⚙️ Mixing Qualified and Unqualified Imports
- 🔧 Best Practices and Common Idioms
- 🧾 Glossary of Key Terms
- 🧭 Conclusion
In Haskell, modules are the primary way to organize code. A module is simply a collection of related definitions—functions, types, and values—that can be imported into other programs.
Example module:
-- File: Math/Geometry.hs
module Math.Geometry (areaCircle) where
areaCircle :: Floating a => a -> a
areaCircle r = pi * r^2To use it elsewhere:
import Math.Geometry
main = print (areaCircle 5)📘 Key Idea: Modules promote modularity, code reuse, and namespace isolation.
By default, every Haskell file automatically imports:
import PreludePrelude provides the most common functions and types (map, foldr, Maybe, etc.).
But you can import other modules manually:
import Data.List
import System.IOThis lets you use everything those modules export.
import Data.List
main = print (sort [3,1,2])Result:
[1,2,3]
If you want only specific functions:
import Data.List (sort, nub)If you want to hide a function:
import Data.List hiding (nub)The base library (installed with GHC) provides all standard modules.
| Category | Example Modules | Description |
|---|---|---|
| Core |
Prelude, Data.List, Data.Maybe
|
Everyday functions & types |
| Control |
Control.Monad, Control.Applicative
|
Functional control structures |
| System |
System.IO, System.Directory
|
File, process, and I/O handling |
| Numeric |
Data.Ratio, Numeric
|
Rational, complex, and numeric utilities |
| Collections |
Data.Map, Data.Set, Data.Sequence
|
Efficient data structures |
| Text |
Data.Text, Data.ByteString
|
String and binary data |
| Debugging | Debug.Trace |
Debug output |
| GHC |
GHC.Base, GHC.Exts
|
Low-level internals |
Example:
import Data.List (sort, nub)
import Control.Monad (forM_)
import System.IO (readFile)When you import a module qualified, its functions and types must be prefixed with the module name.
This prevents naming conflicts between modules that export functions with the same name.
import qualified Data.List
main = print (Data.List.nub [1,1,2,3])✅ Prevents name clashes ✅ Makes origins of functions explicit ✅ Improves readability in large projects ✅ Supports modular namespace design
import Data.List
import Data.Set
main = print (map (*2) (fromList [1,2,3]))❌ Error:
Ambiguous occurrence ‘map’
It could refer to either ‘Data.List.map’ or ‘Data.Set.map’
import qualified Data.List
import qualified Data.Set
main = do
print (Data.List.map (*2) [1,2,3])
print (Data.Set.map (*2) (Data.Set.fromList [1,2,3]))Now Haskell knows exactly which map you mean.
You can create shorter aliases using as — a very common idiom in Haskell.
import qualified Data.List as L
import qualified Data.Set as SThen:
main = do
print (L.nub [1,1,2,3])
print (S.member 2 (S.fromList [1,2,3]))💡 Common alias conventions:
| Module | Alias | Example |
|---|---|---|
Data.List |
L |
L.sort [3,1,2] |
Data.Map |
M |
M.lookup "key" m |
Data.Set |
S |
S.fromList [1,2,3] |
Data.Text |
T |
T.pack "hello" |
Data.ByteString |
B |
B.pack [72,101,108,108,111] |
You can use both styles in the same file for balance between brevity and clarity.
import Data.List (sort)
import qualified Data.List as L
main = do
print (sort [3,1,2]) -- unqualified
print (L.nub [1,1,2,3]) -- qualified✅ Guideline:
Use unqualified imports for commonly used, unambiguous functions (like sort),
and qualified ones for context-specific or conflicting names (nub, map, etc.).
import qualified Data.Map as M
import qualified Data.Set as SHelps differentiate between M.map and S.map.
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
main = TIO.putStrLn (T.pack "Hello, Haskell!")Prefer explicit imports:
import Data.List (sort, nub)✅ Keeps code maintainable and avoids pollution of the global namespace.
You can hide Prelude entirely:
{-# LANGUAGE NoImplicitPrelude #-}
import qualified Prelude as P
main = P.print (P.map (+1) [1,2,3])Used in advanced libraries (e.g., embedded DSLs, smart contract DSLs).
| Term | Meaning |
|---|---|
| Module | A file or namespace containing related definitions. |
| Import | Brings names from another module into scope. |
| Qualified Import | Requires names to be prefixed by module or alias. |
Alias (as) |
A shorthand prefix for a qualified module. |
| Prelude | The automatically imported base module with common functions. |
| Namespace | Logical grouping of identifiers to prevent naming clashes. |
| Export List | Controls what a module exposes (module M (f, g, h) where). |
| NoImplicitPrelude | Compiler flag disabling automatic Prelude import. |
✅ Haskell modules are a powerful feature for building clean, modular, and reusable programs. ✅ Qualified imports and aliases make large projects manageable by keeping namespaces clear. ✅ Use explicit imports to prevent ambiguity and improve readability.
Once you master imports, your Haskell codebase becomes organized, conflict-free, and easy to navigate — no matter how large it grows.
Bernard Sibanda is a global Technology Entrepreneur, Web3 and Software Consultant with a deep focus on Cardano Blockchain, Midnight and Community building.
Key Positions:
- Founder, CTO, Developer Advocate cohort #1, Fullstake Developer, Cardano Ambassador, Catalyst Project Manager, DREP-WIMS:
- Co-founder of ABL Tech and Cardano Africa Live
- EBU-certified Plutus Pioneer (Plutus/Haskell)
- Cohort #1 Plutus Pioneer Developer
- Catalyst Community Reviewer & Funded Projects Manager
-
DRep for WIMS-Cardano (ID:
drep1yguj8zu48n99pv70yl6ckzt9hdgjy8yjnlqs2uyzcpafnjgu4vkul) - Intersect Developer Advocate
- Intersect Committe Member 2025-2026
- Cardano Marketer,Promoter and blogger
- Cardano Open Source Contributor
- Cardano communities and events organizer and builder
- Cardano Ambassador for South Africa
Official links:
- Stablecoins Dex
- Coxygen Global Universities
- WIMS Cardano Global
- Cardano Africa Live
- WIMS Cardano Videos
- Cardano Smart Contract Videos
- Fullstack IT Consulting
Social links: