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