临时变量

可以用 let ... in ...where ... 语法定义临时变量,where 可以后置定义,而 let in 则是前置

1
2
3
4
5
6
7
8
9
10
11
solve :: Int -> Int -> [Int] -> String
solve n m doors = do
case indices of
[] -> "YES"
_ -> case end - start + 1 of
x | x <= m -> "YES"
_ -> "NO"
where
indices = elemIndices 1 doors
end = last indices
start = head indices

模式匹配

Enumeration Matching

最基础的 Pattern Matching 就是,可以把变量的所有可能取值都枚举出来。用 _ 匹配所有其他情况

1
2
3
4
5
greet :: String -> String -> String
greet "Finland" name = "Hei, " ++ name
greet "Italy" name = "Ciao, " ++ name
greet "England" name = "How do you do, " ++ name
greet _ name = "Hello, " ++ name

Condition Guards

在变量后面加 | <conditions> 可以用条件控制 pattern matching,即对变量进行条件约束。用 otherwise 表示所有其他条件

case of 语法的区别在于:condition guards 需要的是 condition 而不是具体的值.

1
2
3
4
5
6
7
describe :: Int -> String
describe n
| n == 2 = "Two"
| even n = "Even"
| n == 3 = "Three"
| n > 100 = "Big!!"
| otherwise = "The number " ++ show n

当然也可以和 Enumeration Matching 进行结合,枚举一部分,另一部分用 Guard 控制

1
2
3
4
5
6
7
8
9
10
guessAge :: String -> Int -> String
guessAge "Griselda" age
| age < 47 = "Too low!"
| age > 47 = "Too high!"
| otherwise = "Correct!"
guessAge "Hansel" age
| age < 12 = "Too low!"
| age > 12 = "Too high!"
| otherwise = "Correct!"
guessAge name age = "Wrong name!"

case of 语法

case ... of 也是按值匹配,而非按条件.

1
2
3
case xxx of
value1 -> return_value1
value2 -> return_value2

不过配合 Guards 也可以做到按条件匹配

1
2
3
case xxx of
x | someguards -> return_value_1
_ -> return_value_2