Я новичок в Haskell, и меня очень смущает Где и Пусть. Кажется, что оба они обеспечивают аналогичную цель. Я прочитал несколько сравнений между Где и Пусть, но у меня возникают проблемы с тем, когда их использовать. Может ли кто-нибудь указать какой-либо контекст или, возможно, несколько примеров, демонстрирующих, когда использовать один над другим?
Где vs. Let
ПредложениеA
where
может быть определено только на уровне определения функции. Обычно это идентично определениюlet
. Единственное различие заключается в том, что охранники используются. Объем предложенияwhere
распространяется на все защитные устройства. Напротив, объем выраженияlet
- это только текущее предложение функции и защита, если таковые имеются.
Haskell Wiki очень подробный и содержит различные случаи, но он использует гипотетические примеры. Я нахожу его объяснения слишком краткими для новичка.
Преимущества Let:
f :: State s a
f = State $ \x -> y
where y = ... x ...
не будет работать, поскольку соответствие шаблона f =, где no 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 упоминается, что предложение Где является декларативным, а выражение Пусть выразительно. Помимо стиля, как они работают по-разному?
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 ...
- В первом примере почему Пусть, но Где нет?
- Можно ли применить Где к первому примеру?
- Можно ли применить это к реальным примерам, где переменные представляют собой фактические выражения?
- Существует ли общее правило для использования каждого из них?
Update
Для тех, кто пришел к этой теме позже, я нашел лучшее объяснение, которое можно найти здесь: "" Нежное введение в Haskell".
Пусть выражения.
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, которое ограничивается только выражением, которое оно охватывает. Предложение where разрешено только на верхнем уровне набора уравнений или выражения case. Те же свойства и ограничения на привязки в выражениях let применяются к тем, где содержатся предложения. Эти две формы вложенной области кажутся очень схожими, но помните, что выражение let является выражением, тогда как предложение where не является - оно является частью синтаксиса объявлений функций и выражений case.