gpt4 book ai didi

Haskell:Where 与 Let

转载 作者:行者123 更新时间:2023-12-03 04:41:36 25 4
gpt4 key购买 nike

我是 Haskell 的新手,我对 WhereLet 感到非常困惑。它们似乎都提供了相似的目的。我读过一些 WhereLet 之间的比较,但我很难辨别何时使用它们。有人可以提供一些背景信息或者一些示例来演示何时使用其中一种而不是另一种吗?

Where vs. 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 Cheat Sheet

Haskell Wiki非常详细并提供了各种案例,但它使用了假设的例子。我发现它的解释对于初学者来说太简短了。

Let 的优点:

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

Control.Monad.State

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 on Advantages of 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)

Declaration vs. Expression

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 ...
  1. 在第一个示例中,为什么 Let 在范围内,而 Where 不在范围内?
  2. 是否可以将Where应用于第一个示例?
  3. 有人可以将此应用于变量代表实际表达式的实际示例吗?
  4. 何时使用每种方法是否有可遵循的一般经验法则?
<小时/>

更新

对于那些稍后访问此线程的人,我在这里找到了最好的解释:“A Gentle Introduction to Haskell ”。

Let Expressions.

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

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

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

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

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

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

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

或者像这样:

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

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

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 来强调程序流程(通过将计算移到后面)。

关于Haskell:Where 与 Let,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4362328/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com