diff options
Diffstat (limited to 'stdlib/source/library/lux/data/collection/stream.lux')
-rw-r--r-- | stdlib/source/library/lux/data/collection/stream.lux | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/stdlib/source/library/lux/data/collection/stream.lux b/stdlib/source/library/lux/data/collection/stream.lux new file mode 100644 index 000000000..f09423882 --- /dev/null +++ b/stdlib/source/library/lux/data/collection/stream.lux @@ -0,0 +1,140 @@ +(.module: + [library + [lux "*" + [abstract + [functor {"+" Functor}] + [comonad {"+" CoMonad}]] + [control + ["//" continuation {"+" Cont}] + ["<>" parser + ["<[0]>" code {"+" Parser}]]] + [macro {"+" with_symbols} + [syntax {"+" syntax:}] + ["[0]" code]] + [data + ["[0]" bit] + [collection + ["[0]" list ("[1]#[0]" monad)]]] + [math + [number + ["n" nat]]]]]) + +(type: .public (Stream a) + (Cont [a (Stream a)])) + +(def: .public (iterations step init) + (All (_ a b) + (-> (-> a [a b]) a (Stream b))) + (let [[next x] (step init)] + (//.pending [x (iterations step next)]))) + +(def: .public (repeated x) + (All (_ a) + (-> a (Stream a))) + (//.pending [x (repeated x)])) + +(def: .public (cycle [start next]) + (All (_ a) + (-> [a (List a)] (Stream a))) + (loop [head start + tail next] + (//.pending [head (case tail + {.#End} + (again start next) + + {.#Item head' tail'} + (again head' tail'))]))) + +(template [<name> <return>] + [(def: .public (<name> stream) + (All (_ a) (-> (Stream a) <return>)) + (let [[head tail] (//.result stream)] + <name>))] + + [head a] + [tail (Stream a)] + ) + +(def: .public (item idx stream) + (All (_ a) (-> Nat (Stream a) a)) + (let [[head tail] (//.result stream)] + (case idx + 0 head + _ (item (-- idx) tail)))) + +(template [<taker> <dropper> <pred_type> <pred_test> <pred_step> <post_test>] + [(def: .public (<taker> pred xs) + (All (_ a) + (-> <pred_type> (Stream a) (List a))) + (let [[x xs'] (//.result xs)] + (if (<post_test> <pred_test>) + (list& x (<taker> <pred_step> xs')) + (list)))) + + (def: .public (<dropper> pred xs) + (All (_ a) + (-> <pred_type> (Stream a) (Stream a))) + (let [[x xs'] (//.result xs)] + (if (<post_test> <pred_test>) + (<dropper> <pred_step> xs') + xs)))] + + [while until (-> a Bit) (pred x) pred |>] + [first after Nat (n.= 0 pred) (-- pred) not] + ) + +(template [<splitter> <pred_type> <pred_test> <pred_step>] + [(def: .public (<splitter> pred xs) + (All (_ a) + (-> <pred_type> (Stream a) [(List a) (Stream a)])) + (let [[x xs'] (//.result xs)] + (if <pred_test> + [(list) xs] + (let [[tail next] (<splitter> <pred_step> xs')] + [{.#Item [x tail]} next]))))] + + [split_when (-> a Bit) (pred x) pred] + [split_at Nat (n.= 0 pred) (-- pred)] + ) + +(def: .public (only predicate stream) + (All (_ a) (-> (-> a Bit) (Stream a) (Stream a))) + (let [[head tail] (//.result stream)] + (if (predicate head) + (//.pending [head (only predicate tail)]) + (only predicate tail)))) + +(def: .public (partition left? xs) + (All (_ a) (-> (-> a Bit) (Stream a) [(Stream a) (Stream a)])) + [(..only left? xs) + (..only (bit.complement left?) xs)]) + +(implementation: .public functor + (Functor Stream) + + (def: (each f fa) + (let [[head tail] (//.result fa)] + (//.pending [(f head) (each f tail)])))) + +(implementation: .public comonad + (CoMonad Stream) + + (def: &functor ..functor) + + (def: out head) + + (def: (disjoint wa) + (let [[head tail] (//.result wa)] + (//.pending [wa (disjoint tail)])))) + +(syntax: .public (^stream& [patterns (<code>.form (<>.many <code>.any)) + body <code>.any + branches (<>.some <code>.any)]) + (with_symbols [g!stream] + (let [body+ (` (let [(~+ (|> patterns + (list#each (function (_ pattern) + (list (` [(~ pattern) (~ g!stream)]) + (` ((~! //.result) (~ g!stream)))))) + list#conjoint))] + (~ body)))] + (in (list& g!stream body+ branches))))) |