我是Haskell的新手,我对Where vs. Let感到非常困惑。它们似乎都提供了相似的目的。我已阅读之间的一些比较哪里和Let但是我很难辨别何时使用它们。有人可以提供一些背景信息,也可以提供一些示例来说明何时使用另一种方法吗?
在哪里与让
甲
where
子句只能在一个函数定义的电平来定义。通常,这与let
定义范围相同。唯一的区别是使用防护装置的时间。该where
条款的范围涵盖了所有保护措施。相反,let
表达式的范围仅是当前函数子句和保护符(如果有)。
该哈斯克尔维基是非常详细,并提供各种案件,但它使用的假设的例子。我觉得对于初学者来说,其解释太简短了。
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 ...
- 在第一个例子,为什么在我们的范围,但如果不是呢?
- 是否可以申请 在哪里第一个例子?
- 有人可以将其应用于变量表示实际表达式的真实示例吗?
- 有什么通用的经验法则可以遵循?
更新资料
对于后来由该主题引起的读者,我在这里找到了最好的解释:“ Haskell的温和介绍 ”。
让表达式。
每当需要嵌套的一组绑定时,Haskell的let表达式就很有用。作为一个简单的示例,请考虑:
let y = a*b f x = (x+y)/y in f c + f d
由let表达式创建的绑定集是相互递归的,并且模式绑定被视为惰性模式(即,它们带有隐式〜)。唯一允许的声明类型是类型签名,函数绑定和模式绑定。
凡条款。
有时,将绑定范围限制在几个保护方程式上很方便,这需要一个where子句:
f x y | y>z = ... | y==z = ... | y<z = ... where z = x*x
请注意,这不能通过let表达式来完成,let表达式只能在其所包围的表达式范围内。where子句仅在一组方程式或case表达式的顶层被允许。let表达式中对绑定的相同属性和约束适用于where子句中的属性和约束。这两种形式的嵌套作用域看起来非常相似,但请记住,let表达式是一个表达式,而where子句不是-它是函数声明和case表达式的语法的一部分。
f = body where x = xbody; y = ybody ...
表示f = let x = xbody; y = ybody ... in body
case .... of ... where
某种表达式?我对此不确定。
let
与where
何时开始学习之间的区别让我感到困惑。我认为最好的理解方法是认识到两者之间的差异很小,因此无需担心。通过非常简单的机械转换where
给出 的含义let
。请参阅haskell.org/onlinereport/decls.html#sect4.4.3.2确实, 这种转换仅出于符号上的方便而存在。