Я новачок у 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 Ця трансформація існує лише для нотаційної зручності.