(.module: [lux #* [control [functor (#+ Functor)] [comonad (#+ CoMonad)] ["." continuation (#+ pending Cont)] ["p" parser]] [macro (#+ with-gensyms) ["." code] ["s" syntax (#+ syntax: Syntax)]] [data ["." bit] [collection ["." list ("#;." monad)]]]]) (type: #export (Sequence a) {#.doc "An infinite sequence of values."} (Cont [a (Sequence a)])) (def: (cycle' x xs init full) (All [a] (-> a (List a) a (List a) (Sequence a))) (case xs #.Nil (pending [x (cycle' init full init full)]) (#.Cons x' xs') (pending [x (cycle' x' xs' init full)]))) (def: #export (iterate f x) {#.doc "Create a sequence by applying a function to a value, and to its result, on and on..."} (All [a] (-> (-> a a) a (Sequence a))) (pending [x (iterate f (f x))])) (def: #export (repeat x) {#.doc "Repeat a value forever."} (All [a] (-> a (Sequence a))) (pending [x (repeat x)])) (def: #export (cycle xs) {#.doc (doc "Go over the elements of a list forever." "The list should not be empty.")} (All [a] (-> (List a) (Maybe (Sequence a)))) (case xs #.Nil #.None (#.Cons x xs') (#.Some (cycle' x xs' x xs')))) (template [ ] [(def: #export ( s) (All [a] (-> (Sequence a) )) (let [[h t] (continuation.run s)] ))] [head a h] [tail (Sequence a) t]) (def: #export (nth idx s) (All [a] (-> Nat (Sequence a) a)) (let [[h t] (continuation.run s)] (if (n/> 0 idx) (nth (dec idx) t) h))) (template [ ] [(def: #export ( pred xs) (All [a] (-> (Sequence a) (List a))) (let [[x xs'] (continuation.run xs)] (if (list& x ( xs')) (list)))) (def: #export ( pred xs) (All [a] (-> (Sequence a) (Sequence a))) (let [[x xs'] (continuation.run xs)] (if ( xs') xs))) (def: #export ( pred xs) (All [a] (-> (Sequence a) [(List a) (Sequence a)])) (let [[x xs'] (continuation.run xs)] (if (let [[tail next] ( xs')] [(#.Cons [x tail]) next]) [(list) xs])))] [take-while drop-while split-while (-> a Bit) (pred x) pred] [take drop split Nat (n/> 0 pred) (dec pred)] ) (def: #export (unfold step init) {#.doc "A stateful way of infinitely calculating the values of a sequence."} (All [a b] (-> (-> a [a b]) a (Sequence b))) (let [[next x] (step init)] (pending [x (unfold step next)]))) (def: #export (filter p xs) (All [a] (-> (-> a Bit) (Sequence a) (Sequence a))) (let [[x xs'] (continuation.run xs)] (if (p x) (pending [x (filter p xs')]) (filter p xs')))) (def: #export (partition left? xs) {#.doc (doc "Split a sequence in two based on a predicate." "The left side contains all entries for which the predicate is #1." "The right side contains all entries for which the predicate is #0.")} (All [a] (-> (-> a Bit) (Sequence a) [(Sequence a) (Sequence a)])) [(filter left? xs) (filter (bit.complement left?) xs)]) (structure: #export functor (Functor Sequence) (def: (map f fa) (let [[h t] (continuation.run fa)] (pending [(f h) (map f t)])))) (structure: #export comonad (CoMonad Sequence) (def: &functor ..functor) (def: unwrap head) (def: (split wa) (let [[head tail] (continuation.run wa)] (pending [wa (split tail)])))) (syntax: #export (^sequence& {patterns (s.form (p.many s.any))} body {branches (p.some s.any)}) {#.doc (doc "Allows destructuring of sequences in pattern-matching expressions." "Caveat emptor: Only use it for destructuring, and not for testing values within the sequences." (let [(^sequence& x y z _tail) (some-sequence-func +1 +2 +3)] (func x y z)))} (with-gensyms [g!sequence] (let [body+ (` (let [(~+ (list;join (list;map (function (_ pattern) (list (` [(~ pattern) (~ g!sequence)]) (` ((~! continuation.run) (~ g!sequence))))) patterns)))] (~ body)))] (wrap (list& g!sequence body+ branches)))))