Modules and imports

Contents
A module file
The export list
Import forms
Qualified imports

A module file

A file is a module, and the module name must match the path from the project root. A file at src/Lib/Text.hs starts with the matching name:

module Lib.Text where shout :: String -> String shout = map toUpper

Without an export list every top-level name is public. That is fine for a small project and a trap for a library, where the internal helpers become part of the contract by accident.

The export list

The list after the module name decides what the outside world sees. Type(..) exports a type together with all its constructors:

module Lib.Text ( shout , Config(..) ) where data Config = Config { width :: Int } helper = "private" -- not exported

Exporting Config without (..) hides the constructor, so callers can receive a value but cannot build one. That is how a module enforces a smart constructor.

Import forms

Three forms cover almost everything: import everything, import a list, or import everything except a list:

import Data.List -- everything import Data.List (sort, nub) -- just these import Data.List hiding (sort) -- everything else import Data.Char (toUpper)

Explicit import lists are documentation. They also keep names from clashing when two modules export the same thing, which happens with map in Prelude and Data.Map.

Qualified imports

A qualified import forces a prefix at every use, which resolves clashes and makes the origin of a function obvious:

import qualified Data.Map as M import qualified Data.Set as S m = M.fromList [("a", 1), ("b", 2)] M.lookup "a" m -- Just 1 S.fromList [3,1,3] -- fromList [1,3]

The short alias keeps lines readable. Import both qualified and unqualified only when you genuinely need both, and expect the compiler to warn about ambiguity when you do not.

Next: Cabal projects

Article author: Arthur Isaev

Related articles
Haskell
Haskell course: zero to hero in 50 lessons
What is Haskell and why it matters
Install the toolchain with GHCup
GHCi: the interactive shell
Your first program
Values with let and where
Types and type signatures
Functions and application
Currying and partial application
Operators, sections, and fixity
if, guards, and pattern guards
case expressions
Pattern matching
Tuples
Lists
Ranges and enumeration
List comprehensions
Recursion replaces loops
map, filter, and foldr
Lambdas and composition
Type classes
Parametric polymorphism
Maybe and null safety
Either and recoverable errors
data: product types
data: sum types
Records
newtype and type synonyms
Recursive data: binary trees
Functor
Applicative
Monad
do notation
IO and purity
Files and IO
Modules and imports
Cabal projects
Dependencies
Testing with HUnit
Property testing with QuickCheck
Laziness and infinite lists
Strictness and space leaks
Folds
Monoids
Traversable
Monad transformers
Errors and exceptions
Concurrency
Parsing with Megaparsec
Capstone: a todo CLI
Hero roadmap: the whole course on one page

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: