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语法要点:
- 注释:
--单行,{- -}多行 - 标识符:变量小写开头,类型大写开头
- 关键字:有特定含义的保留字
- 操作符:符号组成,有优先级
- 布局规则:缩进决定代码块
- 代码规范:添加类型签名,遵循命名约定
掌握这些基础知识后,让我们继续学习Haskell的数据类型。
最后更新:2026-03-27