liveBook · Manning

Module

As explained in Learn Haskell by Example

A Haskell module is a source-code unit that groups related definitions and controls their visibility through imports and exports.

A Haskell module is a source file that groups related definitions. Its declaration names the module, and that name normally follows the file path: `Graph.hs` defines `Graph`, while `Foo/Bar/Module.hs` defines `Foo.Bar.Module`. Modules make a project easier to divide into focused pieces of library code and executable code. section 2.1.3 section 5.1.2 section 2.1.2

Export a small interface

An export list after the module name chooses what other modules can use. Here, callers can use `square` but do not automatically receive every definition in the file. `module Lib (square) where` `square :: Int -> Int` `square x = x * x` section 2.1.3

Use `import` to bring another module’s exported definitions into scope. Importing without restrictions brings in its whole export list. When names clash, qualify a use with its module name, such as `ModuleName.x`; clashes become more likely as a module imports more code. section 2.1.3 section 5.3

Separate the entry point from reusable code

A typical executable has `Main` as its entry-point module. It imports a library module, then its `main` action calls an exported definition. This keeps reusable functionality in `src` while `app` starts the program. `module Main where` `import Lib` `main :: IO ()` `main = someFunc` section 2.1.3 section 2.1.2

Use module boundaries to shape a project’s public interface:

  • Put definitions for one concern together, such as graph-related functions in `Graph` or line-numbering types and transformations in a library module. section 5.1.2 section 4.4.2
  • Export the types and functions that form the intended interface, while keeping implementation details out of client modules. section 4.4.2
  • Keep pure core functionality in a library module and use it from an executable module that performs input and output. section 4.4.2
  • Avoid tangled dependencies: name conflicts and cyclical imports can prevent compilation. section 7.4.2
Listing 7.15 A re-export of modules
module Csv
  ( module Csv.Conversion,  #1
    module Csv.Types,
  )
where

import Csv.Conversion     #2
import Csv.Types

A top-level module can re-export several focused modules, giving clients one import for related functionality while preserving the internal directory structure. section 7.4.2

How Learn Haskell by Example covers it

How deep it goes
Explains declarations, path-based names, exports, imports, qualification, and re-exports, while deferring deeper compilation details.
Examples
Uses Lib and Main, Graph, a line-numbering library, and a Csv re-export module.
What it assumes
Teaches module structure from a new Stack project while postponing the meaning of IO actions.
What you can do after
Build it from scratch by naming files, declaring modules, selecting exports, importing dependencies, and arranging reusable code.
How it connects
Connects imports, export lists, name clashes, cyclic imports, pure code, IO, and project structure.

Also explained in

Compare how 35 books explain module →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Haskell by Example. The section links point to the parts of the book it draws on.