内容简介:写好模式,Haskell 会直接帮你匹配。如:载入之后运行但是注意,如果把 lucky x 挪到 lucky 7 前面,就永远匹配不到 lucky 7 了。
写好模式,Haskell 会直接帮你匹配。如:
lucky :: Int -> String lucky 7 = "7 is the lucky number!" lucky x = "sorry, you are not lucky" 复制代码
载入之后运行
λ> lucky 2 "sorry, you are not lucky" λ> lucky 3 "sorry, you are not lucky" λ> lucky 7 "7 is the lucky number!" 复制代码
但是注意,如果把 lucky x 挪到 lucky 7 前面,就永远匹配不到 lucky 7 了。
- 用模式匹配实现阶乘:
factorial :: Int -> Int factorial 0 = 1 factorial n = n * factorial (n - 1) 复制代码
- 定义模式的时候,一定在最后留一个万能模式,否则可能会出错
- 元组的模式匹配
addVectors :: (Double, Double) -> (Double, Double) -> (Double, Double) addVectors a b = (fst a + fst b, snd a + snd b) -- 可以改写为 addVectors :: (Double, Double) -> (Double, Double) -> (Double, Double) addVectors (x1, y1) (x2, y2) = (x1 + x2, y1 + y2) 复制代码
-
模式中可以用
_来占位,这个_叫做泛变量 -
可以用
x: _来匹配列表的第一个元素 x,但是要记得加圆括号,不然 Haskell 无法理解它
head' :: [a] -> a head' [] = error "Can' t call head on an empty list, dummy!" -- error 会中断程序 head' (x:_) = x -- 这里的圆括号不是 tuple 的标记 复制代码
(x:y:_) all@(x:items)
守卫/哨卫 guard
bmiTell :: Double -> String
bmiTell weight height
| weight / height ^ 2 <= 18.5 = putStrLn "你体重不足,就像根竹竿!"
| weight / height ^ 2 <= 25.0 = putStrLn "你体重正常,那你肯定是个丑逼!"
| weight / height ^ 2 <= 30.0 = putStrLn "你体重超过,快减肥吧肥宅!"
| otherwise = putStrLn "你是猪!"
复制代码
其中的 bmi < 18.5 就是一个 guard。 每条 guard 语句至少缩进一个空格。 如果当前模式的守卫都没有 True,而且也没有写 otherwise,就会进入下一个模式。
where
可以使用 where 来对计算结果进行缓存,也可以定义其他的帮助函数:
bmiTell :: Double -> String
bmiTell weight height
| bmi <= 18.5 = putStrLn "你体重不足,就像根竹竿!"
| bmi <= 25.0 = putStrLn "你体重正常,那你肯定是个丑逼!"
| bmi <= 30.0 = putStrLn "你体重超过,快减肥吧肥宅!"
| otherwise = putStrLn "你是猪!"
where bmi = weight / height ^ 2
x = "whatever"
getBmi weight height = weight / height ^ 2
复制代码
where 只在当前模式中有效。
就算没有 guard,也可以在函数定义中使用 where:
calcBmis :: [(Double, Double)] -> [Double]
calcBmis xs = [bmi w h | (w, h)< - xs]
where bmi weight height = weight / height ^ 2
复制代码
what 还能这样用
describeList :: [a] -> String
describeList ls = "The list is " ++ what ls
where what [] = "empty."
what [x] = "a singleton list."
what xs = "a longer list."
复制代码
其中 what ls
是以 ls 为参数调用 what 函数。
let
ghci> 4 * (let a = 9 in a + 1) + 2 42 复制代码
let 和 where 相似,不同点在于 where 只允许我们在函数底部绑定变量,且对当前模式可见。而 let 可以出现在任何地方,且 let 里面的变量只在 in 内有效。
另一个区别就是 let 是表达式(有值),而 where 不是。
case
case <exp> of pattern1 -> result1
pattern2 -> result2
pattern3 -> result3
复制代码
模式匹配不过是 case 的语法糖,而且模式匹配只能用在函数定义里,而 case 可以用在任何地方。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Agile Web Development with Rails, Third Edition
Sam Ruby、Dave Thomas、David Heinemeier Hansson / Pragmatic Bookshelf / 2009-03-17 / USD 43.95
Rails just keeps on changing. Rails 2, released in 2008, brings hundreds of improvements, including new support for RESTful applications, new generator options, and so on. And, as importantly, we’ve a......一起来看看 《Agile Web Development with Rails, Third Edition》 这本书的介绍吧!