Цикл бесконечно на Lazy-Seq - PullRequest
       0

Цикл бесконечно на Lazy-Seq

0 голосов
/ 24 сентября 2018

Почему вторая оценка с butlast бесконечно зацикливается в Clojure?

user=> (->> (range) butlast lazy-seq (take 0))
()
user=> (->> (range) butlast lazy-seq first) ; ...

Эквивалент в Haskell может быть достаточно ленивым.

ghci> take 0 . init $ [0..]
[]
ghci> head . init $ [0..]
0

Редактировать

дубль 0 не работает, как указано ниже.

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Почему второй цикл вычислений бесконечно в Clojure?

butlast не ленив, поскольку он перечисляет всю входную последовательность и создает новую коллекцию, пока не исчерпает ввод.

В обеих версиях butlast устраняет лень в восходящем потоке, поэтому я думаю, что еще один важный вопрос: «Почему первая версия когда-либо возвращается, когда задействовано butlast?»: take 0 не работает- он не использует входную последовательность, когда n не является положительным числом, поэтому не имеет значения, что вы передаете его.

Кроме того, я думаю, что эквивалентный код Clojure дляhead . tail $ [0..] было бы:

(->> (range) rest first) ;; => 1

butlast является своего рода противоположностью того, что вы хотели бы.

0 голосов
/ 24 сентября 2018

Если вы посмотрите на реализацию butlast, вы увидите, что она стремится (используя loop вместо lazy-seq).Альтернативная ленивая реализация будет делать то, что вы хотите:

(defn butlast'
  "Like clojure.core/butlast but lazy."
  [xs]
  (when (seq xs)
    ((fn f [[x & xs]]
       (if (seq xs)
         (lazy-seq (cons x (f xs)))
         ()))
     xs)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...