How to define the partitions (factorizations w.r.t. concatenation) of a sequence as a lazy sequence of lazy sequences in Clojure

后端 未结 1 1169
醉酒成梦
醉酒成梦 2021-01-27 18:44

I am new to Clojure and I want to define a function pt taking as arguments a number n and a sequence s and returning all the partitions of

相关标签:
1条回答
  • 2021-01-27 19:22

    The cons call in your split inline fn is the only place where eagerness is being introduced. You could replace that with something that lazily constructs a list, like concat:

    (defn pt [n s]
      (lazy-seq
       (if (zero? n)
         (when (empty? s) [nil])
         ((fn split [a b]
            (concat
             (map (partial concat [a]) (pt (dec n) b))
             (when-let [[bf & br] (seq b)] (split (conj a bf) br))))
          [] s))))
    
    (every? #(= clojure.lang.LazySeq (class %)) (pt 3 [0 1 2 3])) ;; => true
    

    But, reading the code I feel like it's fairly unClojurey, and I think that's to do with the use of recursion. Often you'd use things like reductions, partition-by, split-at and so to do this sort of thing. I feel like there should also be a way to make this a transducer and separate out the lazyness from the processing (so you can use sequence to say you want it lazily), but I haven't got time to work that out right now. I'll try and come back with a more complete answer soon.

    0 讨论(0)
提交回复
热议问题