关于clojure:如何扁平化和懒惰地连接列表列表

How to flatten and lazily concat a list of lists

我在玩弄懒惰的清单,似乎无法弄清楚。我想我可以把它写成一个大的递归函数来解决我的问题,它可以完成所有必要的工作,但是我想用更简单的函数来组成它。

我将尝试写一个简单的例子,可以很容易地转化为我的问题:

1
2
3
4
5
6
(defn numbers
  ([] (numbers 1))
  ([n] (cons n (lazy-seq (numbers (inc n))))))

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

所以,我们有两个函数。一个返回一个懒惰的数字序列。另一个返回它的数字参数n次(希望它也是懒惰的;如果不是,写一个似乎很容易)。

我想将repeat-n映射到数字,以便返回延迟的结果序列。我在lazy-seqlazy-catconcat和递归函数方面做了一些工作,但是我仍然有一些问题。

函数应该是这样的

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

以及(希望)呼叫的结果

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

会是

1
12233344445

有什么想法吗?


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

函数mapconcat和组合mapcat以及repeatrange都是懒惰的。

清单理解,for也是懒惰的。

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