模块基础 #

一、模块概念 #

1.1 什么是模块 #

模块是Haskell代码的组织单位,用于:

  • 封装代码
  • 管理命名空间
  • 控制可见性
  • 组织代码结构

1.2 模块语法 #

haskell
-- 模块定义
module ModuleName (exports) where

-- 模块名与文件路径对应
-- module Data.List 在 Data/List.hs
-- module MyLib.Utils 在 MyLib/Utils.hs

1.3 基本模块 #

haskell
-- MyModule.hs
module MyModule where

-- 定义
greeting :: String
greeting = "Hello, World!"

add :: Int -> Int -> Int
add x y = x + y

二、导出列表 #

2.1 导出语法 #

haskell
-- 导出列表
module MyModule (
    -- 导出的内容
    greeting,
    add,
    Person(..),
    Config(..),
    module Data.List
) where

2.2 导出函数 #

haskell
module Math (
    -- 导出函数
    add,
    subtract,
    multiply
) where

add :: Int -> Int -> Int
add x y = x + y

subtract :: Int -> Int -> Int
subtract x y = x - y

multiply :: Int -> Int -> Int
multiply x y = x * y

-- 内部函数不导出
internalHelper :: Int -> Int
internalHelper = (*2)

2.3 导出类型 #

haskell
module Types (
    -- 导出类型和所有构造器
    Person(..),
    -- 导出类型但不导出构造器
    Secret,
    -- 导出类型和部分构造器
    Result(..)
) where

-- Person类型完全导出
data Person = Person
    { name :: String
    , age  :: Int
    } deriving (Show)

-- Secret类型不导出构造器(抽象类型)
data Secret = Secret String
    deriving (Show)

-- 只能使用模块提供的函数操作
createSecret :: String -> Secret
createSecret = Secret

revealSecret :: Secret -> String
revealSecret (Secret s) = s

-- Result部分导出
data Result a
    = Success a
    | Failure String
    deriving (Show)

2.4 导出类型类 #

haskell
module MyClasses (
    -- 导出类型类和所有方法
    MyShow(..),
    -- 导出类型类但不导出某些方法
    MyEq(myEq)
) where

class MyShow a where
    myShow :: a -> String
    myShowPrec :: Int -> a -> String
    myShowList :: [a] -> String

class MyEq a where
    myEq :: a -> a -> Bool
    myNe :: a -> a -> Bool
    myNe x y = not (myEq x y)

三、模块结构 #

3.1 标准模块结构 #

haskell
-- MyLib/Data.hs
module MyLib.Data (
    -- 类型导出
    Point(..),
    Vector(..),
    
    -- 函数导出
    distance,
    magnitude,
    normalize,
    
    -- 重导出
    module Data.Maybe
) where

import Data.Maybe

-- 类型定义
data Point = Point Double Double
    deriving (Show, Eq)

data Vector = Vector Double Double
    deriving (Show, Eq)

-- 函数定义
distance :: Point -> Point -> Double
distance (Point x1 y1) (Point x2 y2) = 
    sqrt ((x2 - x1)^2 + (y2 - y1)^2)

magnitude :: Vector -> Double
magnitude (Vector x y) = sqrt (x^2 + y^2)

normalize :: Vector -> Vector
normalize v@(Vector x y) = 
    let m = magnitude v
    in Vector (x / m) (y / m)

3.2 分组导出 #

haskell
module MyLib (
    -- 类型
    module MyLib.Types,
    
    -- 工具函数
    module MyLib.Utils,
    
    -- 核心功能
    module MyLib.Core
) where

import MyLib.Types
import MyLib.Utils
import MyLib.Core

3.3 层次化模块 #

haskell
-- MyLib/Data/Point.hs
module MyLib.Data.Point (
    Point(..),
    distance
) where

data Point = Point Double Double

-- MyLib/Data/Vector.hs
module MyLib.Data.Vector (
    Vector(..),
    magnitude
) where

data Vector = Vector Double Double

-- MyLib/Data.hs
module MyLib.Data (
    module MyLib.Data.Point,
    module MyLib.Data.Vector
) where

import MyLib.Data.Point
import MyLib.Data.Vector

四、Main模块 #

4.1 Main模块 #

haskell
-- Main.hs
module Main where

main :: IO ()
main = do
    putStrLn "Hello, World!"

4.2 Main模块特点 #

haskell
-- Main模块可以省略模块声明
-- 以下等价:

-- 方式1
module Main where
main = putStrLn "Hello"

-- 方式2(省略)
main = putStrLn "Hello"

五、模块最佳实践 #

5.1 命名约定 #

haskell
-- 模块名使用驼峰命名
-- 好
module Data.Text
module Network.HTTP.Client
module MyLib.Utils

-- 不好
module data.text
module network_http_client

5.2 导出组织 #

haskell
module MyLib (
    -- 类型
    Config(..),
    Result(..),
    
    -- 核心函数
    initialize,
    process,
    cleanup,
    
    -- 工具函数
    helper1,
    helper2
) where

5.3 文档注释 #

haskell
-- | 这是一个示例模块
--
-- 提供基本的数据处理功能
module MyLib (
    -- * 类型
    Config(..),
    
    -- * 函数
    initialize,
    process
) where

-- | 配置类型
data Config = Config
    { host :: String
    , port :: Int
    }

-- | 初始化
initialize :: Config -> IO ()
initialize cfg = ...

六、总结 #

模块基础要点:

  1. 模块定义module Name (exports) where
  2. 导出列表:控制可见性
  3. 导出类型Type(..) 导出所有,Type 不导出构造器
  4. 重导出module Some.Module
  5. 层次结构:使用点分隔的模块名
  6. Main模块:程序入口,可省略声明

掌握模块基础后,让我们继续学习导入与导出。

最后更新:2026-03-27