169 lines
4.3 KiB
Clojure
169 lines
4.3 KiB
Clojure
(ns Stream
|
|
"Elixir Stream module — lazy, composable enumerables.
|
|
|
|
In CljElixir: (Stream/map coll f), (Stream/filter coll f), etc.
|
|
Streams are lazy: operations are only executed when the stream is consumed
|
|
(e.g., by Enum/to-list, Enum/take, etc.).")
|
|
|
|
(defn map
|
|
"Lazily maps `fun` over `enumerable`.
|
|
(-> [1 2 3] (Stream/map (fn [x] (* x 2))) (Enum/to-list)) ;=> [2 4 6]"
|
|
[enumerable fun])
|
|
|
|
(defn filter
|
|
"Lazily filters elements.
|
|
(-> [1 2 3 4] (Stream/filter (fn [x] (> x 2))) (Enum/to-list)) ;=> [3 4]"
|
|
[enumerable fun])
|
|
|
|
(defn reject
|
|
"Lazily rejects elements where `fun` returns truthy."
|
|
[enumerable fun])
|
|
|
|
(defn flat-map
|
|
"Lazily maps and flattens."
|
|
[enumerable fun])
|
|
|
|
(defn take
|
|
"Lazily takes `count` elements.
|
|
(-> (Stream/iterate 0 inc) (Stream/take 5) (Enum/to-list)) ;=> [0 1 2 3 4]"
|
|
[enumerable count])
|
|
|
|
(defn take-while
|
|
"Lazily takes while `fun` returns truthy."
|
|
[enumerable fun])
|
|
|
|
(defn take-every
|
|
"Lazily takes every `nth` element."
|
|
[enumerable nth])
|
|
|
|
(defn drop
|
|
"Lazily drops `count` elements."
|
|
[enumerable count])
|
|
|
|
(defn drop-while
|
|
"Lazily drops while `fun` returns truthy."
|
|
[enumerable fun])
|
|
|
|
(defn chunk-by
|
|
"Lazily chunks by result of `fun`."
|
|
[enumerable fun])
|
|
|
|
(defn chunk-every
|
|
"Lazily chunks into groups of `count`.
|
|
(-> [1 2 3 4 5] (Stream/chunk-every 2) (Enum/to-list)) ;=> [[1 2] [3 4] [5]]"
|
|
([enumerable count])
|
|
([enumerable count step])
|
|
([enumerable count step leftover]))
|
|
|
|
(defn chunk-while
|
|
"Lazily chunks with custom accumulator logic."
|
|
[enumerable acc chunk-fun after-fun])
|
|
|
|
(defn concat
|
|
"Lazily concatenates enumerables.
|
|
(-> (Stream/concat [1 2] [3 4]) Enum/to-list) ;=> [1 2 3 4]"
|
|
([enumerables])
|
|
([first rest]))
|
|
|
|
(defn dedup
|
|
"Lazily removes consecutive duplicates."
|
|
([enumerable]))
|
|
|
|
(defn dedup-by
|
|
"Lazily removes consecutive duplicates by `fun`."
|
|
[enumerable fun])
|
|
|
|
(defn each
|
|
"Lazily invokes `fun` for side effects. Elements pass through.
|
|
(-> [1 2 3] (Stream/each (fn [x] (IO/puts x))) Enum/to-list)"
|
|
[enumerable fun])
|
|
|
|
(defn scan
|
|
"Lazily emits successive reduced values.
|
|
(-> [1 2 3 4] (Stream/scan 0 +) Enum/to-list) ;=> [1 3 6 10]"
|
|
([enumerable fun])
|
|
([enumerable acc fun]))
|
|
|
|
(defn transform
|
|
"Lazily transforms with an accumulator."
|
|
[enumerable acc reducer after-fun])
|
|
|
|
(defn uniq
|
|
"Lazily removes duplicates."
|
|
[enumerable])
|
|
|
|
(defn uniq-by
|
|
"Lazily removes duplicates by `fun`."
|
|
[enumerable fun])
|
|
|
|
(defn with-index
|
|
"Lazily adds indices.
|
|
(-> [:a :b :c] Stream/with-index Enum/to-list) ;=> [{:a 0} {:b 1} {:c 2}]"
|
|
([enumerable])
|
|
([enumerable offset]))
|
|
|
|
(defn zip
|
|
"Lazily zips enumerables.
|
|
(-> (Stream/zip [1 2 3] [:a :b :c]) Enum/to-list) ;=> [{1 :a} {2 :b} {3 :c}]"
|
|
([enumerables])
|
|
([enum1 enum2]))
|
|
|
|
(defn zip-with
|
|
"Lazily zips with a merge function."
|
|
([enumerables zip-fun])
|
|
([enum1 enum2 zip-fun]))
|
|
|
|
;; --- Generators ---
|
|
|
|
(defn iterate
|
|
"Generates an infinite stream by repeatedly applying `fun`.
|
|
(-> (Stream/iterate 0 inc) (Stream/take 5) Enum/to-list) ;=> [0 1 2 3 4]"
|
|
[start-value next-fun])
|
|
|
|
(defn repeatedly
|
|
"Generates a stream by calling `fun` repeatedly.
|
|
(-> (Stream/repeatedly (fn [] (rand 10))) (Stream/take 3) Enum/to-list)"
|
|
([fun])
|
|
([count fun]))
|
|
|
|
(defn unfold
|
|
"Generates a stream with an accumulator. `fun` returns {emit, next-acc} or nil.
|
|
(-> (Stream/unfold 5 (fn [n] (if (> n 0) {n (- n 1)} nil)))
|
|
Enum/to-list) ;=> [5 4 3 2 1]"
|
|
[acc fun])
|
|
|
|
(defn resource
|
|
"Creates a stream with setup/cleanup. Useful for external resources.
|
|
(Stream/resource
|
|
(fn [] (File/open! \"file.txt\"))
|
|
(fn [file] ...)
|
|
(fn [file] (File/close file)))"
|
|
[start-fun next-fun after-fun])
|
|
|
|
(defn cycle
|
|
"Repeats an enumerable infinitely.
|
|
(-> (Stream/cycle [1 2 3]) (Stream/take 7) Enum/to-list) ;=> [1 2 3 1 2 3 1]"
|
|
[enumerable])
|
|
|
|
(defn interval
|
|
"Emits incrementing integers at `interval` milliseconds.
|
|
(-> (Stream/interval 1000) (Stream/take 3) Enum/to-list) ;=> [0 1 2] (1s apart)"
|
|
[interval])
|
|
|
|
(defn timer
|
|
"Emits a single value of 0 after `delay` milliseconds.
|
|
(-> (Stream/timer 1000) Enum/to-list) ;=> [0]"
|
|
[delay])
|
|
|
|
(defn run
|
|
"Consumes the stream for side effects. Returns :ok."
|
|
[stream])
|
|
|
|
(defn intersperse
|
|
"Lazily intersperses `separator` between elements."
|
|
[enumerable separator])
|
|
|
|
(defn map-every
|
|
"Lazily maps `fun` over every `nth` element."
|
|
[enumerable nth fun])
|