Любое вышеупомянутое.
существуют многие, много лучших вещей разглагольствовать. Такой как, какая цветная кора удовлетворяет дереву лучше всего, я думаю неопределенный коричневый с оттенками приятного мха.
Как объясняет ephemient, вы не можете использовать предложения where
так, как вы это делаете.
Ошибка возникает из-за того, что в этом коде:
main =
return [1..10] >>= \list ->
print list'
where
list' = reverse list
Предложение where
прикреплено к функции main.
Вот та же функция с большим количеством круглых скобок:
main = return [1..10] >>= (\list -> print list')
where
list' = reverse list
Я думаю, что это довольно очевидно почему вы получаете ошибку « вне области
»: привязка для списка
находится глубоко внутри выражения main
, а не что-то вроде где
пункт может достигнуть.
Что я обычно делаю в этой ситуации (и меня много раз кусало то же самое). Я просто представляю функцию и передаю список
в качестве аргумента.
main = do
list <- return [1..10]
let list' = f list
print list'
where
f list = reverse list -- Consider renaming list,
-- or writing in point-free style
Конечно, Я предполагаю, что ваш реальный код в функции f
намного больше, чем просто обратный
, и поэтому вы хотите, чтобы он был внутри предложения where
вместо встроенного пусть
привязка. Если код внутри функции f
очень маленький, я бы просто написал его внутри привязки let
, и не пришлось бы тратить время на введение новой функции.
Насколько я могу судить, предложение where используется только в локальных привязках . Внутренняя часть оператора привязки >> (=) не является локальной привязкой (два разных вида привязки в этом предложении).
Сравните с этим:
main = f [1..10]
f list =
putStrLn "where clause test:" >> print list'
where list' = reverse list
Вы можете обратиться к Haskell 98 отчет о синтаксисе - не уверен, насколько это поможет.
Если я ошибаюсь, кто-то обязательно поправит меня, но я почти уверен, что вы вообще не можете использовать предложение where в том стиле, в котором вы показано выше. list
никогда не будет попадать в область действия предложения where, если это не параметр функции.
Проблема в том, что let
- в
- это выражение, которое можно использовать внутри других выражений, а где
может может использоваться только в объявлении (модуль | класс | экземпляр | GADT | ...) или привязке (функция | шаблон).
Из отчета Haskell 98 о объявлениях и привязках ,
p | g 1
=
e 1
| g 2=
e 2
…
| г m=
e m
, где {
decls}
- сахар для
p
= let
declsв
if
g 1then
e 1else
if
g 2затем
e 2else
…
if
g mthen
e melse error «Несовпадающий образец»
или, упрощая ситуацию путем удаления ограждений,
p
] =
eгде {
decls}
- сахар для
p
= let
declsв
e
in привязки функций и шаблонов. Это верно, даже если ваш e представляет собой конструкцию do {
… }
.
Если вы хотите, чтобы привязка была локальной для определенного подвыражения в пределах большее выражение, вам нужно использовать let
- в
(или просто let
внутри do
, но это просто сахар для let
- в
).
Вы даже не можете написать
main = do
putStrLn "where clause test: "
list <- return [1..10]
(print list' where list' = reverse list)
, потому что « e где {
decls }
»