Ответ 1
Есть три похожих (но разных) способа определения здесь:
-
Вы можете присоединить предложения
where
после определенных определений - в основном привязки стиля уравнения. Таким образом, вы можете поместить его в конце своей функции или после чего-то определенного с помощьюlet
или окруженияwhere
. -
С другой стороны,
let x = ... in ...
- это выражение, которое вычисляет часть послеin
, которая является единственным местом, где видны элементы послеlet
. -
Внутри блока
do
, потому что уже есть неявное вложение области (вещи видны после их определения), вы можете использовать толькоlet x = ...
. Это действительно то же самое, что и предыдущая форма - остальная часть блокаdo
послеlet
является фактически частьюin ...
.
Если вы хотите, чтобы локальное определение использовало что-то определенное в блоке do
, ваш единственный выбор - третий (или передача другого значения (ов) в качестве аргумента (ов)). Однако для независимых вспомогательных функций, таких как ваш пример, работает любой стиль. Вот ваш пример, чтобы продемонстрировать каждый:
Первый стиль, где func
отображается в любом месте foo
, включая все, что определено в предложении where
:
foo = do ...
mapM_ func aList
...
return aValue
where func x = x + 1
Второй стиль, где func
отображается только внутри выражения let
, который в этом случае является целым блоком do
:
foo = let func x = x + 1
in do
...
mapM_ func aList
...
return aValue
И третий стиль, определяющий его внутри блока do
. В этом случае func
видна только после let
; в первом ...
он еще не определен.
foo = do ...
let func x = x + 1
mapM_ func aList
...
return aValue
О, и для хорошей меры: Поскольку let ... in ...
является выражением, вы также можете использовать его везде, где есть выражение, чтобы назвать некоторые локальные определения. Итак, вот еще один пример:
foo = do ...
let func x = x + 1 in mapM_ func aList
...
return aValue
Как и прежде, func
отображается только внутри выражения let
, которое в этом случае является единственным выражением после него, больше нигде.