[解決済み] ハスケル Where vs. Let
質問
私はHaskellの初心者ですが、以下の点で非常に混乱しています。 ここで vs. させる . どちらも似たような目的を提供しているようです。という比較をいくつか読んだことがあります。 とは vs. させる がありますが、それぞれをどのような時に使うのか判別するのに苦労しています。どなたか、文脈や、いつどちらかを使うべきかを示すいくつかの例を示していただけませんか?
Where vs. Let
A
where
節は関数定義のレベルでのみ定義することができます。通常、これはlet
の定義と同じです。 唯一の違いは、ガードが使用されている場合です . のスコープはwhere
節のスコープは全てのガードに及びます。これに対してlet
式のスコープは、もしあれば、現在の関数節とガードのみです。
この Haskell Wiki は非常に詳しく、様々なケースを提供していますが、仮定的な例を使っています。初心者の方には説明が短すぎると思います。
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によると、宣言は ここで 節は宣言的であるのに対して とする。 式は表現的です。スタイルは別として、どのようにパフォーマンスが異なるのでしょうか?
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式は、ネストされたバインディングのセットが必要なときに 必要なときに便利です。簡単な例として を考えてみましょう。
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節においても同じである。これら2つの入れ子スコープは非常に似ているように見えますが、let式は式であるのに対し、where句はそうではないことを思い出してください。
どのように解決するのですか?
1: 例の問題
f :: State s a
f = State $ \x -> y
where y = ... x ...
はパラメータ
x
. の中のものは
where
節にあるものは、関数のパラメータのみを参照することができます。
f
のパラメータ(何もない)と外部スコープにあるものだけを参照できます。
2:使用するには
where
を使うには、2つ目の名前付き関数
を受け取る
x
のように、パラメータとして指定します。
f = State f'
f' x = y
where y = ... x ...
とかこんな感じ。
f = State f'
where
f' x = y
where y = ... x ...
3: 以下、完全な例として
...
'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: どのような場合に
let
または
where
は好みの問題です。私は
let
を使って計算を強調し(前面に移動させ)
where
でプログラムの流れを強調する(計算を後ろに移動させる)ことができます。
関連
-
[解決済み] なぜHaskellでは整数の割り算ができないのか?
-
[解決済み] 解釈の仕方 (Eq a)
-
[解決済み] let "と "var "の使い分けは?
-
[解決済み] Hindley-Milnerのどの部分が理解できないのでしょうか?
-
[解決済み] Project Eulerとの速度比較。CとPythonとErlangとHaskellの比較
-
[解決済み] Haskellにはなぜ "data "と "newtype "があるのですか?重複] [重複] [重複
-
[解決済み] GHCはなぜこんなに大きいのか/大きいのか?
-
[解決済み】Haskellの入門編
-
[解決済み] なぜ依存型でないのか?
-
[解決済み] Haskellのマルチコアプログラミングはどうなっているのか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】なぜパースエラーになるのか?インデント?
-
[解決済み] Haskell - Ord aの型は何を意味するのでしょうか?
-
[解決済み] haskellにおけるdrop関数 - リスト内包を用いた実装
-
[解決済み] Haskell タプルをリスト化する?
-
[解決済み] RustのtraitとHaskellのtypeclassの違いは何ですか?
-
[解決済み] 制約条件付き特殊化
-
[解決済み] Haskell における `mod` と `rem` の違い
-
[解決済み] GHCiの複数行コマンド
-
[解決済み] ハスケル Where vs. Let
-
[解決済み] Haskellでグラフはどのように表現するのか?