Я новачок у Haskell, і мене дуже збентежило Where vs. Let . Вони, схоже, забезпечують подібну мету. Я прочитав кілька порівнянь між Де vs. Нехай , але у мене виникають проблеми , коли Discerning використовувати кожен. Може хтось, будь ласка, надати якийсь контекст чи, можливо, кілька прикладів, які демонструють, коли потрібно використовувати один над іншим?
Де проти Нехай
whereРозділ може бути визначений тільки на рівні визначення функції. Зазвичай це ідентично областіletвизначення. Єдина відмінність полягає в тому, коли використовуються охоронці . Обсяг цьогоwhereпункту поширюється на всіх охоронців. На відміну від цього, сфераletвиразу - це лише поточне положення функції та захист, якщо вони є.
Haskell Wiki дуже докладно і надає різні випадки , але він використовує гіпотетичні приклади. Я вважаю його пояснення занадто короткими для початківця.
Переваги Let :
f :: State s a
f = State $ \x -> y
where y = ... x ...
не буде працювати, тому що де посилається на узор, що відповідає f =, де жоден х не знаходиться в області застосування. Навпаки, якби ви почали з дозволу, то у вас не виникло б проблем.
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 згадує про те , що де становище є декларативним , а Нехай вираз виразність. Як вони відрізняються від стилю?
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" в області, а де " ні"?
- Чи можна застосувати Де до першого прикладу?
- Чи можуть деякі застосувати це до реальних прикладів, коли змінні представляють фактичні вирази?
- Чи є загальне правило, яке слід дотримуватися, коли використовувати кожен?
Оновлення
Для тих, хто пізніше піде за цією ниткою, я знайшов тут найкраще пояснення: " Ніжне введення в Хаскелл ".
Нехай вирази.
Дозволені вирази Haskell корисні, коли потрібен вкладений набір прив’язок. Як простий приклад розглянемо:
let y = a*b f x = (x+y)/y in f c + f dНабір зв'язків, створених висловом let, взаємно рекурсивний, а прив'язки малюнків трактуються як ледачі візерунки (тобто вони несуть неявний ~). Єдиний вид дозволених декларацій - це підписи типів, прив'язки функцій та прив'язки шаблонів.
Де Клаузи.
Іноді зручно застосовувати прив'язки до кількох захищених рівнянь, для чого потрібне застереження де:
f x y | y>z = ... | y==z = ... | y<z = ... where z = x*xЗауважте, що це неможливо зробити з виразом let, який охоплює лише той вираз, який він додає. Де застереження дозволено лише на верхньому рівні набору рівнянь або виразів випадок. Ті ж властивості та обмеження щодо прив’язок у виразах дозволених застосовуються до тих, де пункти. Ці дві форми вкладених областей здаються дуже схожими, але пам’ятайте, що вираз let - це вираз, тоді як, де застереження - ні, це частина синтаксису функцій оголошень та виразів випадок.
f = body where x = xbody; y = ybody ...означаєf = let x = xbody; y = ybody ... in body
case .... of ... whereякось перетворити вираз на долю в вираз? Я не впевнений у цьому.
letіwhereколи я вперше почав вивчати Haskell. Я думаю, що найкращий спосіб зрозуміти це - усвідомити, що різниця між ними є дуже малою, і тому нічого турбуватися. Сенс, щоwhereподається в термінахletчерез дуже просте механічне перетворення. Дивіться haskell.org/onlinereport/decls.html#sect4.4.3.2 Ця трансформація існує лише для нотаційної зручності.