If I've understood your problem correctly, clojure.core/lazy-cat does exactly what you need.
Ray. On 22 November 2017 at 22:31, Stephen Nelson <[email protected]> wrote: > ``` > (->> (repeatedly > (fn [] > (lazy-seq > (println "New seq...") > (map (fn [x] + x (rand-int 10)) (range 4))))) > (apply concat) > (take 1)) > New seq... > => (3) > ``` > > Lazy-flatten is unnecessary because concat already does what you want – > the generalised problem you're running in to is that function arguments are > eagerly realised. In your case, your use of concat realises the first two > seqs, in my example, `apply` realises the first four elements (see the > implementation of apply). > > If you wrap the seq generator in `lazy-seq` you can delay the realisation > of the 'expensive' inner sequence until concat reaches that list. In > implementation terms, lazy-seq is a macro returns a thunk that will delay > the println (and the sequence generation) until it's required by concat. > > On Thu, Nov 23, 2017 at 2:32 AM Matt Anderson <[email protected]> > wrote: > >> Thanks! The `aconcat` solution from plumbing works great for this use >> case. >> >> The `lazy-gen`/`yield` fn's in Tupelo are exactly what I was searching >> for in terms of a larger abstraction, but couldn't quite put into words. >> Thanks for the tip! >> >> >> >> On Wednesday, November 22, 2017 at 2:36:18 AM UTC-5, Alan Thompson wrote: >> >>> You can also solve this using `lazy-gen` and `yield-all` from the >>> Tupelo library >>> <https://github.com/cloojure/tupelo#generator-functions-for-lazy-sequences-a-la-python>. >>> It allows you to make >>> a lazy generator function (a la Python): >>> >>> (let [seq-of-seqs [(range 0 5) >>> (range 10 15) >>> (range 20 25)] >>> flat-seq (lazy-gen >>> (doseq [curr-seq seq-of-seqs] >>> (yield-all curr-seq)))] >>> (is= flat-seq [0 1 2 3 4 10 11 12 13 14 20 21 22 23 24])) >>> >>> >>> Alan >>> >>> On Tue, Nov 21, 2017 at 4:47 PM, Jason Wolfe <[email protected]> wrote: >>> >> I think this >>>> <https://github.com/plumatic/plumbing/blob/318af7798bb701607aaae8639d12829014941184/src/plumbing/core.cljx#L182> >>>> will do it: >>>> >>>> (lazy-cat (first coll) (when-let [n (next coll)] (lazy-flatten n)))) >>>> >>>> >>>> On Tuesday, November 21, 2017 at 2:34:15 PM UTC-8, Matt Anderson wrote: >>>>> >>>>> I have a function that is returning a lazy-seq of lazy-seq's. >>>>> >>>>> >>>>> (seq (seq [1 2 3]) (seq [4 5 6]) ...) >>>>> >>>>> >>>>> The end-user API, however, should be able to get back a lazy-seq of >>>>> the individual items across all lazy-seq's--essentially a flattening of >>>>> the >>>>> output of my function--instead of the "top level" seqs. >>>>> >>>>> >>>>> (seq [1 2 3 4 5 6 ...]) >>>>> >>>>> Each of the internal lazy-seq's is expensive in terms of memory usage >>>>> so I'd like to only "load" one at a time. I've been trying to find a way >>>>> to only calculate one of the top-level lazy-seq's at a time and then not >>>>> "take" the next until the user gets to the end of the first and needs the >>>>> first item from the next (eg: (seq [4 5 6]) doesn't get calculated until >>>>> we >>>>> have consumed 3 and are asking for the next), but haven't found a way to >>>>> do >>>>> it. Best I've gotten is "loading" 2 "top level" seqs at a time and I'm >>>>> afraid that may be the best I get, but I thought it might be an exercise >>>>> worth presenting in case anyone had ideas. Here's a contrived example: >>>>> >>>>> >>>>> (defn lazy-flatten >>>>> >>>>> [coll] >>>>> >>>>> (when-let [s (seq coll)] >>>>> >>>>> (lazy-seq >>>>> >>>>> (if (seq? (first s)) >>>>> >>>>> (concat (lazy-flatten (first s)) (lazy-flatten (rest s))) >>>>> >>>>> (cons (first s) (lazy-flatten (rest s))))))) >>>>> >>>>> (->> (repeatedly >>>>> (fn [] >>>>> (println "New seq...") >>>>> (map (fn [x] + x (rand-int 10)) (range 4)))) >>>>> lazy-flatten >>>>> (take 1)) >>>>> >>>>> >>>>> >>>>> Prints: >>>>> >>>>> >>>>> New seq... >>>>> >>>>> New seq... >>>>> >>>>> => (8) >>>>> >>>>> >>>>> I realize this is because 2 items must be taken for "concat", so there >>>>> would need to be another approach (this was just my best shot >>>>> implementation). >>>>> >>>>> >>>>> Any ideas on how to get the bottom form to only print 1 "New seq..."? >>>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "Clojure" group. >>>> >>> To post to this group, send email to [email protected] >>>> >>> >>>> Note that posts from new members are moderated - please be patient with >>>> your first post. >>>> To unsubscribe from this group, send email to >>>> >>> [email protected] >>>> >>> >>>> For more options, visit this group at >>>> http://groups.google.com/group/clojure?hl=en >>>> --- >>>> You received this message because you are subscribed to the Google >>>> Groups "Clojure" group. >>>> >>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to [email protected]. >>>> >>> >>>> For more options, visit https://groups.google.com/d/optout. >>>> >>> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to [email protected] >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> [email protected] >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> For more options, visit https://groups.google.com/d/optout. >> > -- > Stephen Nelson | Platform Lead Developer | Montoux > e. [email protected] <[email protected]> > t. @montoux > w. montoux.com > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to [email protected] > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > [email protected] > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to [email protected] Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
