haskell 的where 或者 let …in 表达式以及if-else嵌套
本地定义
本地定义允许您将事情分解为更简单的步骤
您可以只编写单独的“帮助”函数,但如果它仅在非常本地的上下文中需要,则本地定义可以使其更具可读性,也可以使用局部定义来避免重复计算。 例如
版本1:
f a = some calculation
g b c = b*(f c) + b/(f c)
f a is calculated twice
比版本1更好的版本:
g b c = b*f + b/f
where
f = some calculation
(involving c)
f 计算一次(但使用了两次),无需将 c 作为参数传递,因为它在同一范围内
示例:二次根(Quadratic Roots)
二次方程𝑎𝑥2+𝑏𝑥+𝑐=0的根由下式给出
roots :: (Float, Float, Float) -> (Float, Float)
roots (a, b, c) = ((-b+s)/d,(-b-s)/d)
where s = sqrt (b*b -4.0*a*c)
d = 2.0*a
做同样事情的另一种方法:
roots :: (Float, Float, Float) -> (Float, Float)
roots (a, b, c) =
let s = sqrt (b*b -4.0*a*c)
d = 2.0*a
in ((-b+s)/d,(-b-s)/d)
let 后跟任意数量的局部定义
in 将这些与主要表达式分开
应该使用 where 还是 let?
“重要的是要知道 let … in … 是一个表达式,也就是说,它可以写在任何允许表达式的地方。 相反, where 绑定到周围的句法结构,例如函数定义的模式匹配行。”
如果你有一个带守卫的函数,那么 let 的范围是单个子句,而 where 适用于整个函数
当我们使用 monad 时,使用 let 有一个优势
除了这两点,选择是风格问题。 我个人认为使用 where 可以让事情更自然地阅读,但除非你使用 let 的方式大大降低了可读性,否则我不会惩罚它。
if-else嵌套
只有一个if -else的情况
if<Condition> then <True-Value>else <False-Value>
嵌套的if else情况
main = do
let var = 26
if var == 0
then putStrLn "Number is zero"
else if var `rem` 2 == 0
then putStrLn "Number is Even"
else putStrLn "Number is Odd"
所以整理出来就是 if () then() else if() then else的模式