Haskell: Where vs. Let
我是哈斯凯尔的新手,我对"让哪里"很困惑。它们似乎都有相似的目的。我读过几篇关于Where和Let的比较文章,但是我很难分辨何时使用它们。有人能提供一些上下文或者一些例子来说明什么时候使用一个而不是另一个吗?
Where vs. Let
A
where clause can only be defined at the level of a function definition. Usually, that is identical to the scope oflet definition. The only difference is when guards are being used. The scope of thewhere clause extends over all guards. In contrast, the scope of alet expression is only the current function clause and guard, if any.
Haskell备忘单
haskell wiki非常详细,提供了各种各样的案例,但它使用了假设的例子。我觉得它的解释对初学者来说太简单了。
LET的优点:
1 2 3 | f :: State s a f = State $ \x -> y where y = ... x ... |
控制单态
will not work, because where refers to
the pattern matching f =, where no x
is in scope. In contrast, if you had
started with let, then you wouldn't
have trouble.
haskell wiki关于let的优势
1 2 3 4 | f :: State s a f = State $ \x -> let y = ... x ... in y |
何处优势:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
声明与表达式
haskell wiki提到where子句是声明性的,而let表达式是表达性的。除了风格,他们的表现如何不同?
1 2 3 4 5 6 | 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 Expressions.
Haskell's let expressions are useful
whenever a nested set of bindings is
required. As a simple example,
consider:
1
2
3 let y = a*b
f x = (x+y)/y
in f c + f dThe set of bindings created by a let
expression is mutually recursive, and
pattern bindings are treated as lazy
patterns (i.e. they carry an implicit
~). The only kind of declarations
permitted are type signatures,
function bindings, and pattern
bindings.Where Clauses.
Sometimes it is convenient to scope
bindings over several guarded
equations, which requires a where
clause:
1
2
3
4 f x y | y>z = ...
| y==z = ...
| y<z = ...
where z = x*xNote that this cannot be done with a let expression, which only scopes over the expression which it encloses. A where clause is only allowed at the top level of a set of equations or case expression. The same properties and constraints on bindings in let expressions apply to those in where clauses. These two forms of nested scope seem very similar, but remember that a let expression is an expression, whereas a where clause is not -- it is part of the syntax of function declarations and case expressions.
1:示例中的问题
1 2 3 | f :: State s a f = State $ \x -> y where y = ... x ... |
是参数
2:要在第一个示例中使用
1 2 3 | f = State f' f' x = y where y = ... x ... |
或者像这样:
1 2 3 4 | f = State f' where f' x = y where y = ... x ... |
3:这里有一个完整的例子,没有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
4:使用
虽然ephemient所指出的关于保护的技术差异,但是在概念上,是否要将主公式放在前面,并在下面定义额外变量(
法律:
1 |
不合法的:
1 |
法律:
1 2 3 4 5 |
不合法:(与ML不同)
1 2 | let vowels ="AEIOUaeiou" in hasVowel = ... |
我发现这个来自lyhfgg的例子很有用:
1 2 | ghci> 4 * (let a = 9 in a + 1) + 2 42 |
换句话说,在上面的示例中,不可能使用