私はHaskellを初めて使用するので、Where対Letで非常に混乱しています。どちらも同じような目的を提供しているようです。WhereとLetの比較をいくつか読んだことがありますが、それぞれをいつ使用するかを見分けるのに問題があります。誰かがコンテキストを提供したり、場合によってはどちらを使用するかを示すいくつかの例を提供してもらえますか?
どこでvs. Let
where
句は、関数定義のレベルで定義することができます。通常、これはlet
定義の範囲と同じです。唯一の違いは、ガードが使用されている場合です。where
条項の範囲はすべてのガードに及びます。対照的に、let
式のスコープは、現在の関数句とガード(存在する場合)のみです。
Haskellのウィキは非常に詳細であり、様々な例を提供していますが、仮想的な例を使用しています。初心者には説明が短すぎます。
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は、Let式は表現力豊かであるのに対し、Where句は宣言的であることを述べています。スタイルとは別に、彼らはどのように異なるパフォーマンスをしますか?
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を適用することは可能ですか?
- 変数が実際の式を表す実際の例にこれを適用できる人はいますか?
- それぞれを使用するときに従うべき一般的な経験則はありますか?
更新
後でこのスレッドから来る人のために、私はここで見つけるべき最良の説明を見つけました:「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句のバインディングにも適用されます。ネストされたスコープのこれら2つの形式は非常によく似ていますが、let式は式ですが、where句はそうではありません。これは、関数宣言とcase式の構文の一部です。
f = body where x = xbody; y = ybody ...
手段f = let x = xbody; y = ybody ... in body
case .... of ... where
どういうわけかlet式を式に変換することは可能ですか?これについてはよくわかりません。
let
し、where
私が最初にHaskellのを学び始めました。それを理解するための最良の方法は、両者の違いがほとんどないことを認識することです。したがって、心配する必要はありません。where
与えられた の意味はlet
、非常に単純な機械的変換によるものです。haskell.org/onlinereport/decls.html#sect4.4.3.2を参照してください。 この変換は、表記上の便宜のためにのみ存在します。