2013-05-29 4 views
2

Я играю с ленивыми списками и, похоже, не понимаю этого. Я думаю, что могу решить свою проблему, написав это как одну большую рекурсивную функцию, которая делает все, что необходимо, но я хотел бы составить ее из более простых функций.Как сгладить и лениво составить список списков

Постараюсь написать простой пример, который должен перевести на мою проблему легко:

(defn numbers 
    ([] (numbers 1)) 
    ([n] (cons n (lazy-seq (numbers (inc n)))))) 

(defn repeat-n [n] 
    (take n (repeat n))) 

Итак, у нас есть две функции. Один возвращает ленивую последовательность чисел. Другой возвращает его параметр числа n раз (надеюсь, он также ленив, а если нет, то легко написать тот, который будет).

Я хотел бы отобразить повтор-n в числах таким образом, чтобы возвращать ленивую последовательность результатов. Я немного поиграл с lazy-seq, lazy-cat, concat и рекурсивными функциями, но у меня все еще есть проблемы с ним.

Функция должна быть что-то вроде этого

(lazy-concat-map [f items] ...) 

И (надеюсь) результатом вызова

(take 11 (lazy-concat-map repeat-n numbers)) 

будет

12233344445 

Любые идеи?

ответ

4
(take 11 (mapcat #(repeat % %) (range))) 
;=> (1 2 2 3 3 3 4 4 4 4 5) 

Функции map, concat (и сочетание mapcat), а также repeat и range все лень.

Список понимание, for, также ленивым

(take 11 (apply concat (for [x (range)] (repeat x x)))) 
;=> (1 2 2 3 3 3 4 4 4 4 5) 
+2

Обратите внимание, что 'for' может помочь избавиться от' применить concat': '(для [х (диапазон) п (повтор хх)] п)' , – kotarak

Смежные вопросы