我是 Haskell 的新手,我对Where vs. Let感到非常困惑。它们似乎都提供了相似的目的。我已经阅读了Where与Let之间的一些比较,但我无法辨别何时使用它们。有人可以提供一些上下文或一些示例来演示何时使用一个而不是另一个?
在哪里与让
where
子句只能在函数定义级别定义。通常,这与定义的范围相同let
。唯一的区别是何时使用警卫。该where
条款的范围涵盖所有警卫。相反,let
表达式的范围只是当前函数子句和保护,如果有的话。
Haskell Wiki非常详细,提供了各种案例,但它使用了假设的示例。我发现它的解释对于初学者来说太简短了。
Let的优点:
f :: State s a
f = State $ \x -> y
where y = ... x ...
将不起作用,因为 where 指的是匹配 f = 的模式,其中没有 x 在范围内。相反,如果您从 let 开始,那么您将不会遇到麻烦。
f :: State s a
f = State $ \x ->
let y = ... x ...
in y
哪里的优点:
f x
| cond1 x = a
| cond2 x = g a
| otherwise = f (h x a)
where
a = w x
f x
= let a = w x
in case () of
_ | cond1 x = a
| cond2 x = g a
| otherwise = f (h x a)
Haskell wiki 提到Where子句是声明性的,而Let表达式是表达性的。除了风格之外,它们的表现有何不同?
Declaration style | Expression-style
--------------------------------------+---------------------------------------------
where clause | let expression
arguments LHS: f x = x*x | Lambda abstraction: f = \x -> x*x
Pattern matching: f [] = 0 | case expression: f xs = case xs of [] -> 0
Guards: f [x] | x>0 = 'a' | if expression: f [x] = if x>0 then 'a' else ...
- 在第一个示例中,为什么Let在范围内但Where不在?
- 是否可以将Where应用于第一个示例?
- 有些人可以将此应用于变量代表实际表达式的真实示例吗?
- 是否有一个一般的经验法则可以遵循何时使用它们?
更新
对于那些后来通过这个线程来的人,我在这里找到了最好的解释:“ Haskell 的简单介绍”。
让表达式。
当需要一组嵌套的绑定时,Haskell 的 let 表达式很有用。作为一个简单的例子,考虑:
let y = a*b f x = (x+y)/y in f c + f d
由 let 表达式创建的绑定集是相互递归的,并且模式绑定被视为惰性模式(即它们带有隐含的 ~)。唯一允许的声明是类型签名、函数绑定和模式绑定。
Where 子句。
有时在几个受保护的方程上进行范围绑定很方便,这需要一个 where 子句:
f x y | y>z = ... | y==z = ... | y<z = ... where z = x*x
请注意,这不能用 let 表达式来完成,它只作用于它所包含的表达式。where 子句只允许在一组方程式或案例表达式的顶层使用。let 表达式中绑定的相同属性和约束适用于 where 子句中的那些。这两种形式的嵌套范围看起来非常相似,但请记住,let 表达式是表达式,而 where 子句不是——它是函数声明和 case 表达式语法的一部分。