Я новичок в Хаскеле, и меня очень смущает Где против Пусть .Они оба, кажется, обеспечивают схожую цель.Я прочитал несколько сравнений между Где против Пусть , но у меня возникают проблемы с выбором, когда использовать каждый из них.Может ли кто-нибудь предоставить какой-то контекст или, возможно, несколько примеров, демонстрирующих, когда использовать один над другим?
Где против Позвольте
Предложение where
может быть определено только вуровень определения функции.Обычно это совпадает с областью определения let
. Разница лишь в том, что используются охранники .Сфера применения where
распространяется на всех охранников.Напротив, область действия выражения let
представляет собой только текущее функциональное предложение и охрану, если таковые имеются.
Шпаргалка Haskell
Haskell Wiki очень подробный и предоставляет различные случаи, но использует гипотетические примеры.Я считаю его объяснения слишком краткими для начинающего.
Преимущества Let :
f :: State s a
f = State $ \x -> y
where y = ... x ...
Control.Monad.State
не будет работать, потому что где ссылается на шаблон, соответствующий f =, где x не находится в области видимости.Напротив, если бы вы начали с let, то у вас не было бы проблем.
Haskell Wiki о преимуществах Let
f :: State s a
f = State $ \x ->
let y = ... x ...
in y
Преимущества Where :
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 упоминается, что Где *Предложение 1061 * является декларативным, а выражение Let - выразительным.Помимо стиля, как они работают по-разному?
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.
Выражения let Haskell полезны всякий раз, когда требуется вложенный набор привязок.В качестве простого примера рассмотрим:
let y = a*b
f x = (x+y)/y
in f c + f d
Набор привязок, созданных выражением let, является взаимно рекурсивным, а привязки шаблонов обрабатываются как ленивые шаблоны (то есть, они несут неявные ~).Единственный вид разрешенных объявлений - это сигнатуры типов, привязки функций и привязки шаблонов.
Where Clauses.
Иногда удобно связывать привязки по нескольким защищенным уравнениям, для чего требуется условие where:
f x y | y>z = ...
| y==z = ...
| y<z = ...
where z = x*x
Обратите внимание, что этого нельзя сделать с помощьюlet expression, которое охватывает только выражение, которое оно заключает.Предложение where допускается только на верхнем уровне набора уравнений или выражения case.Те же свойства и ограничения для привязок в выражениях let применяются к тем, в которых предложения where.Эти две формы вложенной области видимости кажутся очень похожими, но помните, что выражение let - это выражение, тогда как предложение where - нет - это часть синтаксиса объявлений функций и выражений case.