ANUCOMP1100Haskell函数式编程澳国立大学编程入门

ANU COMP1100 Haskell 编程攻略:函数式编程入门、Pattern Matching、递归完整指南

4 min read

ANU(Australian National University,澳大利亚国立大学)的 COMP1100 Programming as Communication 是 CS 专业最出名的"第一关"——它不用 Python 或 Java,而是用 Haskell,一种纯函数式编程语言。

对于绝大多数来自中国的留学生,Haskell 是一种从来没见过的编程思路。习惯了"命令式编程"(告诉计算机怎么一步一步做)的同学,需要切换到"声明式编程"(告诉计算机你要什么)。这个思维跳跃是 COMP1100 最大的难关。


为什么 ANU 用 Haskell 教编程?

ANU 的哲学是:让学生先学"正确"的编程方式——Haskell 的类型系统非常严格,能编译通过的程序通常逻辑上是正确的。学完 Haskell 之后,学 Python/Java 会更容易理解程序的本质。

Imperial College London 也用 Haskell 教 CO 120,所以这份指南对 Imperial 学生同样适用。


第一部分:Haskell 基础概念

1.1 函数式编程的核心思想

命令式(Python/Java)函数式(Haskell)
用变量存储状态,逐步修改没有可变变量,用函数变换数据
for / while 循环递归代替循环
函数可能有副作用纯函数,相同输入必有相同输出
类型可以隐式转换强类型,类型错误编译时报错

1.2 基础语法

-- 定义一个函数:接受两个整数,返回它们的和
add :: Int -> Int -> Int
add x y = x + y

-- 使用
add 3 4  -- 结果:7

类型签名(Type Signature)

  • Int -> Int -> Int 表示接受 Int,返回"接受 Int 的函数",最终返回 Int
  • 这体现了 Currying(柯里化):所有函数本质上都是单参数函数

1.3 基本数据类型

-- 基础类型
42      :: Int          -- 整数
3.14    :: Double       -- 浮点数
True    :: Bool         -- 布尔值
'a'     :: Char         -- 单字符
"hello" :: String       -- 字符串(Char 的列表)

-- 列表(List)
[1, 2, 3]       :: [Int]
['a', 'b', 'c'] :: [Char]  -- 等同于 String "abc"

-- 元组(Tuple)
(1, True)       :: (Int, Bool)
(1, 2, 3)       :: (Int, Int, Int)

第二部分:Pattern Matching(模式匹配)

Pattern Matching 是 Haskell 最核心、也是 COMP1100 考试最多的内容。

2.1 基础 Pattern Matching

-- 对布尔值 Pattern Matching
not' :: Bool -> Bool
not' True  = False
not' False = True

-- 对数字 Pattern Matching
factorial :: Int -> Int
factorial 0 = 1                         -- 基础情形(Base Case)
factorial n = n * factorial (n - 1)     -- 递归情形(Recursive Case)

执行顺序:从上到下匹配第一个符合的模式。

2.2 对列表 Pattern Matching

-- [] 匹配空列表
-- (x:xs) 匹配"第一个元素 x + 剩余列表 xs"

myLength :: [a] -> Int
myLength []     = 0                       -- 空列表长度为 0
myLength (_:xs) = 1 + myLength xs         -- 非空:1 + 剩余长度

myHead :: [a] -> a
myHead (x:_) = x
myHead []    = error "empty list"

mySum :: [Int] -> Int
mySum []     = 0
mySum (x:xs) = x + mySum xs

2.3 Guards(守卫条件)

classify :: Int -> String
classify n
  | n < 0     = "negative"
  | n == 0    = "zero"
  | n < 10    = "small"
  | otherwise = "large"

第三部分:高阶函数(Higher-Order Functions)

高阶函数是 Haskell 的精髓,COMP1100 期末必考。

3.1 map、filter、foldr

-- map:对列表每个元素应用函数
map :: (a -> b) -> [a] -> [b]
map (*2) [1,2,3]   -- [2,4,6]
map even [1,2,3,4] -- [False,True,False,True]

-- filter:保留满足条件的元素
filter :: (a -> Bool) -> [a] -> [a]
filter even [1,2,3,4,5]  -- [2,4]
filter (>3) [1,2,3,4,5]  -- [4,5]

-- foldr:从右向左"折叠"列表(右折叠)
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr (+) 0 [1,2,3]   -- 0+3+2+1 = 6(实际上是 1+(2+(3+0)))
foldr (:) [] [1,2,3]  -- [1,2,3](复制列表)

3.2 Lambda 表达式(匿名函数)

-- 传统写法
double :: Int -> Int
double x = x * 2

-- Lambda 写法
double = \x -> x * 2

-- 在 map 中直接使用
map (\x -> x * x) [1,2,3,4]  -- [1,4,9,16]

3.3 函数组合(Function Composition)

-- (.) 是函数组合运算符
(f . g) x = f (g x)

-- 例:先过滤偶数,再翻倍
doubleEvens :: [Int] -> [Int]
doubleEvens = map (*2) . filter even
-- 等价于:doubleEvens xs = map (*2) (filter even xs)

doubleEvens [1,2,3,4,5]  -- [4,8]

第四部分:自定义类型(Custom Types)

4.1 代数数据类型(Algebraic Data Types)

-- 定义一个 Shape 类型
data Shape = Circle Double
           | Rectangle Double Double
           | Triangle Double Double Double

-- 计算面积(Pattern Matching on custom type)
area :: Shape -> Double
area (Circle r)        = pi * r * r
area (Rectangle w h)   = w * h
area (Triangle a b c)  = let s = (a+b+c)/2
                          in sqrt (s*(s-a)*(s-b)*(s-c))

4.2 Maybe 类型(安全处理可能失败的情况)

-- Maybe a 要么是 Nothing(无值),要么是 Just a(有值)
safeDiv :: Int -> Int -> Maybe Int
safeDiv _ 0 = Nothing
safeDiv x y = Just (x `div` y)

-- 使用
safeDiv 10 2  -- Just 5
safeDiv 10 0  -- Nothing

COMP1100 考试/作业常见错误

错误原因修复
无限递归(Stack Overflow)忘记写 Base Case确保有终止条件
类型错误(Type Error)函数签名与实现不符检查类型签名,或先不写让 GHC 推断
Pattern 未覆盖(Non-exhaustive)没有处理所有情况otherwise_ 通配符
show / read 混淆show 把值转为字符串,read 反向明确数据流方向

备考策略

  1. 先理解类型系统:Haskell 的错误信息很长,但类型错误是最常见的,学会读类型签名
  2. 大量练习 Pattern Matching:这是 COMP1100 的核心,特别是列表的递归处理
  3. 在 GHCi 中即时测试ghci 是 Haskell 的交互式 REPL,随时测试小函数
  4. 画递归调用树:帮助理解递归逻辑,特别是 foldrfoldl 的执行顺序

相关资源:

✍️

Essay 还是没思路?Deadline 快到了?

发作业 brief 给客服,30 分钟内回复,帮你拆解题目、梳理论证逻辑。

扫码咨询发 Brief · 30 分钟报价