2015-02-19 4 views
0

Я выполнил ленивый генератор простого числа (nextprime возвращает следующий премьер, начиная с номера прошел):Наручников внутри ленивой функции генератора простого числа в Clojure

(defn allprimes 
    ([] (allprimes 2)) 
    ([x] (lazy-seq (cons (nextprime x) (allprimes (nextprime x)))))) 

Давайте предположим, что nextprime является дорогостоящей функция для того, не выполнять это в два раза я пытался привязки его к символу:

(defn allprimes 
    ([] (allprimes 2)) 
    ([x] (let [next (nextprime x)] 
     (cons next (lazy-seq (allprimes (next))))))) 

Но это не работает (java.lang.Long не может быть приведен к clojure.lang.IFn). Зачем?

Кроме того, есть ли разница между (cons n (lazy-seq ...)) и (lazy-seq (cons n ...))?

Редактировать: спасибо Kyle за указание ошибки в первом вопросе. Если скобки будут удалены из следующего, это сработает.

+0

'next' находится в положении функции. Попробуйте удалить parens - '(allprimes next)' – Kyle

+0

Спасибо, первый вопрос закрыт ... Я чувствую себя настолько немым! – lightlazer

+0

Также посмотрите на 'iterate', который создает для вас ленивый seq -' (def allprimes (iterate nextprime 2)) ' – Kyle

ответ

0

У вас есть дополнительные скобки вокруг (next): next затем вызывается как функция IFn хотя next является Long ...

Для вашего второго вопроса, пример в Лас clojure doc дает подробную информацию о разнице между 2-решений ,

Примерно (cons n (lazy-seq ...)) всегда будет оценивать n, даже если он не потребляется, и (lazy-seq (cons n ...)) полностью ленив. Это может иметь значение, если n - это не просто число, но и некоторые функции, которые могут быть интенсивными.