Haskell - where

Haskell - where

引入一个小案例

1
2
3
4
5
6
bmiTest :: Double -> Double -> String
bmiTest weight height
| weight / height ^ 2 <= 18.5 = "Underweight"
| weight / height ^ 2 <= 25 = "Normal"
| weight / height ^ 2 <= 30 = "Overweight"
| otherwise = "Obese"

这是一个简单的bmi指数测试函数,使用了前一篇的guard完成,这样写挺好,但是还是不够完美。这里对bmi数值有三次重复的计算,如果输入的数据走到了otherwise就会算三次,血亏!
让我们稍加修改一下代码:

1
2
3
4
5
6
7
8
9
10
bmiTestV2 :: Double -> Double -> String
bmiTestV2 weight height
| bmi <= underWeight = "Underweight"
| bmi <= normal = "Normal"
| bmi <= overWeight = "Overweight"
| otherwise = "Obese"
where bmi = weight / height ^ 2
underWeight = 18.5
normal = 25
overWeight = 30

看着代码应该就明白这个怎么回事了,但是有一点需要吐槽,就是这个缩进问题,他不是像python那样固定缩进到一个代码块就ok了,而是变量定义都必须对齐到同一列,如果不这样规范,Haskell就会搞不清楚他们各自位于哪个代码块中了。

where的作用域

函数where部分定义的名字只对本函数可见,所以不用担心存在大量的全局函数污染代码。当然如果想要一个全局变量,那么反而是要自己定义一下的。

where中的模式模式匹配

在where中也可以使用到模式匹配,修改前面的BMI函数

1
2
3
4
5
6
7
8
bmiTestV2 :: Double -> Double -> String
bmiTestV2 weight height
| bmi <= underWeight = "Underweight"
| bmi <= normal = "Normal"
| bmi <= overWeight = "Overweight"
| otherwise = "Obese"
where bmi = weight / height ^ 2
(underWright, normal, overHeight) = (18.5, 25.0, 30.0)

where块中的函数

在where中也可以定义函数,美滋滋属于是了。

1
2
3
calcBmis :: [(Double. Double)] -> [Double]
calcBmis xs = [bmi w h | (w, h) <- xs]
where bmi weight height = weight / height ^ 2

Haskell - where
http://cvrain.cloudvl.cn/2023/11/16/Haskell/haskell-where/
作者
ClaudeRainer
发布于
2023年11月16日
许可协议