aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/data/collection/stream.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/library/lux/data/collection/stream.lux')
-rw-r--r--stdlib/source/library/lux/data/collection/stream.lux140
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)))))