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.

Reply via email to