Haskell: я могу использовать, где пункт после блока со связывает операторы (>> =)?

Любое вышеупомянутое.

существуют многие, много лучших вещей разглагольствовать. Такой как, какая цветная кора удовлетворяет дереву лучше всего, я думаю неопределенный коричневый с оттенками приятного мха.

10
задан sth 21 July 2009 в 22:10
поделиться

3 ответа

Как объясняет 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 , и не пришлось бы тратить время на введение новой функции.

11
ответ дан 3 December 2019 в 17:21
поделиться

Насколько я могу судить, предложение where используется только в локальных привязках . Внутренняя часть оператора привязки >> (=) не является локальной привязкой (два разных вида привязки в этом предложении).

Сравните с этим:

main = f [1..10]

f list =
    putStrLn "where clause test:" >> print list'
        where list' = reverse list

Вы можете обратиться к Haskell 98 отчет о синтаксисе - не уверен, насколько это поможет.

Если я ошибаюсь, кто-то обязательно поправит меня, но я почти уверен, что вы вообще не можете использовать предложение where в том стиле, в котором вы показано выше. list никогда не будет попадать в область действия предложения where, если это не параметр функции.

1
ответ дан 3 December 2019 в 17:21
поделиться

Проблема в том, что let - в - это выражение, которое можно использовать внутри других выражений, а где может может использоваться только в объявлении (модуль | класс | экземпляр | GADT | ...) или привязке (функция | шаблон).

Из отчета Haskell 98 о объявлениях и привязках ,

p | g 1 = e 1
| g 2 = e 2

| г m = e m
, где { decls }

- сахар для

p = let decls в
if g 1 then e 1 else
if g 2 затем e 2 else

if g m then e m else 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 } »

11
ответ дан 3 December 2019 в 17:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: