Haskell:Where vs. Let [英] Haskell: Where vs. Let

查看:26
本文介绍了Haskell:Where vs. Let的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Haskell 的新手,我对 WhereLet 感到非常困惑.它们似乎都提供了类似的目的.我已经阅读了 WhereLet 之间的一些比较,但我无法辨别何时使用它们.有人可以提供一些上下文或一些示例来说明何时使用一个而不是另一个吗?

I am new to Haskell and I am very confused by Where vs. Let. They both seem to provide a similar purpose. I have read a few comparisons between Where vs. Let but I am having trouble discerning when to use each. Could someone please provide some context or perhaps a few examples that demonstrate when to use one over the other?

Where vs. Let

Where vs. Let

where 子句只能在函数定义级别进行定义.通常,这与 let 定义的范围相同.唯一的区别是何时使用守卫.where 子句的范围扩展到所有守卫.相比之下,let 表达式的作用域只是当前的函数子句和守卫(如果有).

A where clause can only be defined at the level of a function definition. Usually, that is identical to the scope of let definition. The only difference is when guards are being used. The scope of the where clause extends over all guards. In contrast, the scope of a let expression is only the current function clause and guard, if any.

Haskell 备忘单

Haskell Wiki 非常详细,提供了各种案例,但使用的是假设性示例.我觉得它的解释对于初学者来说太简短了.

The Haskell Wiki is very detailed and provides various cases but it uses hypothetical examples. I find its explanations too brief for a beginner.

Let的优势:

f :: State s a
f = State $ x -> y
   where y = ... x ...

Control.Monad.State

不起作用,因为 where 指的是匹配 f = 的模式,其中没有 x在范围内.相反,如果你有从 let 开始,然后你就不会有麻烦了.

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.

关于 Let 优势的 Haskell Wiki

f :: State s a
f = State $ x ->
   let y = ... x ...
   in  y

Where 的优势:

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 表达式是表达性的.除了风格之外,他们的表现有何不同?

The Haskell wiki mentions that the Where clause is declarative while the Let expression is expressive. Aside from style how do they perform differently?

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 ...

  1. 在第一个示例中,为什么 Let 在范围内,而 Where 不在?
  2. 是否可以将 Where 应用于第一个示例?
  3. 有些人可以将此应用于变量代表实际表达式的真实示例吗?
  4. 是否有一般的经验法则可遵循何时使用?
  1. In the first example why is the Let in scope but Where is not?
  2. Is it possible to apply Where to the first example?
  3. Can some apply this to real examples where the variables represent actual expressions?
  4. Is there a general rule of thumb to follow when to use each?

<小时>

更新

对于那些后来通过这个线程来的人,我找到了最好的解释:Haskell 简介".

Let 表达式.

Haskell 的 let 表达式很有用每当一组嵌套的绑定是必需的.举个简单的例子,考虑:

Haskell's let expressions are useful whenever a nested set of bindings is required. As a simple example, consider:

let y   = a*b
    f x = (x+y)/y
in f c + f d

由 let 创建的绑定集表达式是相互递归的,并且模式绑定被视为惰性模式(即它们带有隐含的~).唯一的声明允许类型签名,函数绑定和模式绑定.

The 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 子句.

有时范围很方便绑定了几个守卫方程,这需要一个 where条款:

Sometimes it is convenient to scope bindings over several guarded equations, which requires a where clause:

f x y  |  y>z           =  ...
       |  y==z          =  ...
       |  y<z           =  ...
     where z = x*x

请注意,这不能通过 let 表达式完成,它仅作用于它所包含的表达式.where 子句只允许出现在一组方程或 case 表达式的顶层.let 表达式中绑定的相同属性和约束适用于 where 子句中的那些.这两种嵌套作用域的形式看起来非常相似,但请记住,let 表达式是一个表达式,而 where 子句则不是——它是函数声明和 case 表达式语法的一部分.

Note 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:例子中的问题

f :: State s a
f = State $ x -> y
    where y = ... x ...

是参数 x.where 子句中的事物只能引用函数f 的参数(没有)和外部作用域中的事物.

is the parameter x. Things in the where clause can refer only to the parameters of the function f (there are none) and things in outer scopes.

2:要在第一个例子中使用where,可以引入第二个命名函数将 x 作为参数,如下所示:

2: To use a where in the first example, you can introduce a second named function that takes the x as a parameter, like this:

f = State f'
f' x = y
    where y = ... x ...

或者像这样:

f = State f'
    where
    f' x = y
        where y = ... x ...

3: 这是一个没有 ... 的完整示例:

3: Here is a complete example without the ...'s:

module StateExample where

data State a s = State (s -> (a, s))

f1 :: State Int (Int, Int)
f1 = State $ state@(a, b) ->
    let
        hypot = a^2 + b^2
        result = (hypot, state)
    in result

f2 :: State Int (Int, Int)
f2 = State f
    where
    f state@(a, b) = result
        where
        hypot = a^2 + b^2
        result = (hypot, state)

4:何时使用 letwhere 是一个品味问题.我使用 let 来强调计算(通过将它移到前面)和 where 来强调程序流程(通过将计算移到后面).

4: When to use let or where is a matter of taste. I use let to emphasize a computation (by moving it to the front) and where to emphasize the program flow (by moving the computation to the back).

这篇关于Haskell:Where vs. Let的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆