Haskell语法基础 #

一、注释 #

Haskell支持单行注释和多行注释。

1.1 单行注释 #

使用 -- 开始:

haskell
-- 这是单行注释
x = 5  -- 行尾注释

-- 计算平方
square x = x * x  -- 返回x的平方

1.2 多行注释 #

使用 {--} 包围:

haskell
{-
  这是多行注释
  可以跨越多行
  用于详细说明
-}

add x y = x + y

{- 也可以用于行内注释 -}

1.3 嵌套注释 #

Haskell支持注释嵌套:

haskell
{-
  外层注释开始
  {- 内层注释 -}
  外层注释结束
-}

1.4 文档注释 #

使用Haddock格式:

haskell
-- | 计算阶乘
-- 
-- >>> factorial 5
-- 120
factorial :: Integer -> Integer
factorial 0 = 1
factorial n = n * factorial (n - 1)

-- | 加法函数
-- 接受两个参数,返回它们的和
add :: Int -> Int -> Int
add x y = x + y

二、标识符 #

2.1 命名规则 #

Haskell标识符分为两类:

变量标识符:以小写字母或下划线开头

haskell
-- 合法的变量名
name = "Haskell"
firstName = "John"
_count = 0
myFunction x = x + 1

-- 非法变量名(以大写开头)
-- Name = "Haskell"  -- 错误!

构造器标识符:以大写字母开头

haskell
-- 合法的类型和构造器名
data Color = Red | Green | Blue

data Person = Person String Int

-- 类型变量使用小写
identity :: a -> a
identity x = x

2.2 命名约定 #

haskell
-- 驼峰命名(推荐)
firstName = "John"
lastName = "Doe"
calculateTotal = sum

-- 下划线命名(不推荐,但合法)
first_name = "John"
last_name = "Doe"

-- 类型参数使用单字母
map :: (a -> b) -> [a] -> [b]

-- 或有意义的名称
map :: (input -> output) -> [input] -> [output]

2.3 操作符命名 #

操作符由符号组成:

haskell
-- 自定义操作符
(+-) :: Int -> Int -> Int
x +- y = x + y - 1

-- 使用反引号将函数变为中缀
add x y = x + y
result = 5 `add` 3  -- 等于 8

三、关键字 #

3.1 保留关键字 #

Haskell保留以下关键字:

关键字 用途
case 模式匹配
class 定义类型类
data 定义数据类型
default 默认定义
deriving 自动派生实例
do do语法块
else 条件分支
foreign 外部函数接口
if 条件表达式
import 导入模块
in let表达式
infix 中缀操作符声明
infixl 左结合中缀操作符
infixr 右结合中缀操作符
instance 类型类实例
let 局部绑定
module 模块定义
newtype 新类型定义
of case匹配
then 条件分支
type 类型别名
where 局部定义
forall 显式全称量词
mdo 递归do块
rec 递归绑定

3.2 关键字使用示例 #

haskell
-- if-then-else
absolute x = if x >= 0 then x else -x

-- case-of
describe 0 = "zero"
describe 1 = "one"
describe _ = "many"

-- let-in
result = let x = 5 in x * x

-- where
area r = pi * r * r
  where pi = 3.14159

-- data
data Maybe a = Nothing | Just a

-- class
class Show a where
    show :: a -> String

-- instance
instance Show Bool where
    show True = "True"
    show False = "False"

四、操作符 #

4.1 基本操作符 #

haskell
-- 算术运算
(+)  :: Num a => a -> a -> a
(-)  :: Num a => a -> a -> a
(*)  :: Num a => a -> a -> a
(/)  :: Fractional a => a -> a -> a
(^)  :: Num a => a -> Int -> a   -- 整数幂
(^^) :: Fractional a => a -> Integer -> a
(**) :: Floating a => a -> a -> a

-- 比较运算
(==) :: Eq a => a -> a -> Bool
(/=) :: Eq a => a -> a -> Bool
(<)  :: Ord a => a -> a -> Bool
(<=) :: Ord a => a -> a -> Bool
(>)  :: Ord a => a -> a -> Bool
(>=) :: Ord a => a -> a -> Bool

-- 逻辑运算
(&&) :: Bool -> Bool -> Bool
(||) :: Bool -> Bool -> Bool
not  :: Bool -> Bool

4.2 函数应用操作符 #

haskell
-- 普通函数应用(最高优先级)
f x = f $ x

-- 低优先级应用
($) :: (a -> b) -> a -> b
f $ x = f x

-- 示例
result = sum $ map (*2) [1..10]
-- 等价于
result = sum (map (*2) [1..10])

4.3 函数组合 #

haskell
-- 组合操作符
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x = f (g x)

-- 示例
doubleAndAddOne = (+1) . (*2)
-- doubleAndAddOne 5 = 11

4.4 列表操作符 #

haskell
-- 构造器
(:) :: a -> [a] -> [a]
1 : [2, 3]  -- [1, 2, 3]

-- 拼接
(++) :: [a] -> [a] -> [a]
[1, 2] ++ [3, 4]  -- [1, 2, 3, 4]

-- 访问
(!!) :: [a] -> Int -> a
[1, 2, 3] !! 1  -- 2

4.5 操作符优先级 #

优先级从0到9,9最高:

haskell
-- 函数应用优先级最高(10)
f x y  -- 从左到右

-- 常见优先级
infixl 9  !!            -- 列表索引
infixr 9  .             -- 函数组合
infixl 8  ^, ^^, **     -- 幂运算
infixl 7  *, /, `div`, `mod`
infixl 6  +, -          -- 加减
infixr 5  ++            -- 列表拼接
infix  4  ==, /=, <, <=, >, >=
infixr 3  &&            -- 逻辑与
infixr 2  ||            -- 逻辑或
infixr 1  >>, >>=       -- Monad操作
infixr 0  $, $!, `seq`  -- 低优先级应用

五、布局规则 #

5.1 缩进规则 #

Haskell使用缩进来确定代码块(布局规则):

haskell
-- 使用缩进
main = do
    putStrLn "Hello"
    putStrLn "World"

-- 等价于使用大括号
main = do { putStrLn "Hello"; putStrLn "World" }

5.2 缩进要求 #

haskell
-- 正确:where块缩进
factorial n
    | n <= 0    = 1
    | otherwise = n * factorial (n - 1)
  where
    helper = ...

-- 错误:缩进不一致
-- factorial n
-- | n <= 0 = 1    -- 错误!缩进不够

5.3 let和where #

haskell
-- let-in表达式
result = let x = 1
             y = 2
         in x + y

-- where子句
area width height = width * height
  where
    width = 10
    height = 5

六、代码规范 #

6.1 类型签名 #

始终添加类型签名:

haskell
-- 推荐
add :: Int -> Int -> Int
add x y = x + y

-- 不推荐(虽然类型推断可以工作)
add x y = x + y

6.2 函数定义 #

haskell
-- 推荐:每个参数单独一行
longFunction :: Int -> Int -> Int -> Int
longFunction a b c = a + b + c

-- 或使用对齐
function :: Int
         -> Int
         -> Int
function x y = x + y

6.3 模块组织 #

haskell
-- 标准模块结构
module MyModule
    ( -- 导出列表
      func1
    , func2
    , Type1(..)
    ) where

-- 导入
import Data.List (sort, nub)
import qualified Data.Map as M

-- 类型定义
data Type1 = ...

-- 函数定义
func1 :: ...
func1 = ...

6.4 命名风格 #

haskell
-- 布尔值使用is/has前缀
isEmpty :: [a] -> Bool
hasElement :: Eq a => a -> [a] -> Bool

-- 转换函数使用to前缀
toString :: Show a => a -> String

-- 危险函数使用unsafe前缀
unsafeHead :: [a] -> a

七、总结 #

Haskell语法要点:

  1. 注释-- 单行,{- -} 多行
  2. 标识符:变量小写开头,类型大写开头
  3. 关键字:有特定含义的保留字
  4. 操作符:符号组成,有优先级
  5. 布局规则:缩进决定代码块
  6. 代码规范:添加类型签名,遵循命名约定

掌握这些基础知识后,让我们继续学习Haskell的数据类型。

最后更新:2026-03-27