).

ичок в Haskell, и я очень смущенкуда противПозволять, Они оба, кажется, обеспечивают схожую цель. Я прочитал несколько сравнений междукуда противПозволять но у меня возникают проблемы с распознаванием, когда использовать каждый из них. Может ли кто-нибудь предоставить какой-то контекст или, возможно, несколько примеров, демонстрирующих, когда использовать один над другим?

Где против

A where Предложение может быть определено только на уровне определения функции. Обычно это идентично объемуlet определение.Разница лишь в том, когда используются охранники, Сфера действияwhere пункт распространяется на всех охранников. Напротив, сфера действияlet Выражение - это только текущее предложение функции и защита, если таковые имеются.

Шпаргалка Haskell

Haskell Wiki очень подробно и предоставляет различные случаи, но он использует гипотетические примеры. Я считаю его объяснения слишком краткими для начинающего.

Преимущества Let:

f :: State s a
f = State $ \x -> y
   where y = ... x ...

Control.Monad.State

не будет работать, потому что где относится к шаблону соответствия 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.

Ответы на вопрос(4)

Ваш ответ на вопрос