Подтвердить что ты не робот

Разница между привязками, привязками и единственным оператором присваивания (<-)

Я не понимаю разницу между тремя синтаксисами:

  • where a = f (b)
  • do a <- f (b)
  • do let a = f (b)

Я действительно понимаю, что a <- f(b) отличается от двух других, в большинстве случаев, когда я пробовал все три работы. Кроме того, я читал где-то в сети, что за блок вы должны попытаться ладить с одним let binding только для того, чтобы быть "идиоматическим". Но я никогда, кажется, не справляюсь.

Как я могу решить, что использовать?

4b9b3361

Ответ 1

let foo = bar in ... просто определяет foo как то же самое, что и bar в контексте ...; вы можете просто использовать текстовую замену, чтобы заменить все применения foo в ... на (bar) и получить тот же результат.

Предложения

where аналогичны выражениям let...in, но идут в конце предложения функции, а не являются выражением. Например,

foo x
    | p1 = ... y ...
    | p2 = ... y ...
  where
    y = ...

Невозможно переписать это с помощью let...in, не меняя защиты в if...then...else s. Зачастую where клаузулы используются по предложениям let...in исключительно по причинам стиля.

Оператор связывания совершенно другой. Он использовался в обозначениях do для "извлечения" значения из монадического вычисления. То есть, если foo имеет тип m a, то после x <- foo, x имеет тип a. Все остальные "привязывающие" формы просто определяют имена, но <- используется для привязки результата вычисления к имени из монады. <- может использоваться только внутри блока do, поэтому он используется исключительно для создания большего вычисления в той же монаде, что и действие, которое вы связываете с результатом.

let foo = bar в do обозначение - просто удобство; вы можете переписать:

do let foo = bar
   ...

а

let foo = bar
in do ...

но это становится беспорядочным, когда у вас много таких привязок, поскольку блоки do проникают глубже и глубже.

Я не знаю, о чем говорят вы упомянутые вами советы; вы можете определить несколько переменных в блоке let...in просто отлично, а

let foo = ...
    bar ...
in ...

более идиоматичен, чем

let foo = ...
in let bar = ...
   in ...