Saya baru mengenal Haskell dan saya sangat bingung dengan Where vs. Let . Keduanya sepertinya memberikan tujuan yang sama. Saya telah membaca beberapa perbandingan antara Where vs. Let tetapi saya kesulitan membedakan kapan harus menggunakan masing-masing. Bisakah seseorang memberikan beberapa konteks atau mungkin beberapa contoh yang menunjukkan kapan harus menggunakan salah satu dari yang lain?
Dimana vs.
Sebuah
where
klausul hanya dapat didefinisikan pada tingkat definisi fungsi. Biasanya, itu identik dengan ruang lingkuplet
definisi. Satu-satunya perbedaan adalah saat penjaga digunakan . Cakupanwhere
klausul meluas ke semua penjaga. Sebaliknya, cakupanlet
ekspresi hanya klausa fungsi saat ini dan penjaga, jika ada.
The Haskell Wiki sangat rinci dan menyediakan berbagai kasus tetapi menggunakan contoh hipotetis. Saya merasa penjelasannya terlalu singkat untuk pemula.
Keuntungan dari Let :
f :: State s a
f = State $ \x -> y
where y = ... x ...
tidak akan bekerja, karena where mengacu pada pola yang cocok dengan f =, di mana tidak ada x dalam ruang lingkup. Sebaliknya, jika Anda memulai dengan biarkan, maka Anda tidak akan mengalami kesulitan.
Haskell Wiki tentang Keuntungan Let
f :: State s a
f = State $ \x ->
let y = ... x ...
in y
Keuntungan Dimana :
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)
Wiki Haskell menyebutkan bahwa klausa Where bersifat deklaratif sedangkan ekspresi Let ekspresif. Selain gaya, bagaimana mereka tampil berbeda?
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 ...
- Pada contoh pertama mengapa Let in scope tapi Where tidak?
- Apakah mungkin untuk menerapkan Di mana contoh pertama?
- Bisakah beberapa menerapkan ini pada contoh nyata di mana variabel mewakili ekspresi sebenarnya?
- Apakah ada aturan umum yang harus diikuti kapan harus menggunakan masing-masing?
Memperbarui
Bagi mereka yang datang melalui utas ini nanti, saya menemukan penjelasan terbaik dapat ditemukan di sini: " Pengantar yang Lembut untuk Haskell ".
Biarkan Ekspresi.
Ekspresi let Haskell berguna setiap kali diperlukan kumpulan bertingkat dari binding. Sebagai contoh sederhana, pertimbangkan:
let y = a*b f x = (x+y)/y in f c + f d
Himpunan binding yang dibuat oleh ekspresi let saling rekursif, dan binding pola diperlakukan sebagai pola malas (yaitu, membawa ~ implisit). Satu-satunya jenis deklarasi yang diizinkan adalah tanda tangan tipe, binding fungsi, dan binding pola.
Dimana Klausul.
Kadang-kadang lebih mudah untuk mengikat lingkup pada beberapa persamaan yang dilindungi, yang membutuhkan klausa where:
f x y | y>z = ... | y==z = ... | y<z = ... where z = x*x
Perhatikan bahwa ini tidak bisa dilakukan dengan ekspresi let, yang hanya mencakup ekspresi yang diapitnya. Klausa where hanya diperbolehkan di tingkat atas dari kumpulan persamaan atau ekspresi kasus. Properti dan batasan yang sama pada binding di biarkan ekspresi diterapkan ke dalam klausa where. Kedua bentuk lingkup bersarang ini tampak sangat mirip, tetapi ingat bahwa ekspresi let adalah ekspresi, sedangkan klausa where bukan - itu adalah bagian dari sintaks deklarasi fungsi dan ekspresi kasus.
f = body where x = xbody; y = ybody ...
artinyaf = let x = xbody; y = ybody ... in body
case .... of ... where
ekspresi? Saya tidak yakin tentang ini.
let
danwhere
saat pertama kali belajar Haskell. Saya pikir cara terbaik untuk memahaminya adalah dengan menyadari bahwa ada sangat sedikit perbedaan antara keduanya, dan oleh karena itu tidak ada yang perlu dikhawatirkan. Arti yangwhere
diberikan dalam pengertianlet
melalui transformasi mekanis yang sangat sederhana. Lihat haskell.org/onlinereport/decls.html#sect4.4.3.2 Transformasi ini ada hanya untuk kenyamanan notasi.