diff options
Diffstat (limited to 'stdlib/source/lux/data')
-rw-r--r-- | stdlib/source/lux/data/collection/dictionary.lux | 11 | ||||
-rw-r--r-- | stdlib/source/lux/data/collection/row.lux | 102 | ||||
-rw-r--r-- | stdlib/source/lux/data/maybe.lux | 1 |
3 files changed, 67 insertions, 47 deletions
diff --git a/stdlib/source/lux/data/collection/dictionary.lux b/stdlib/source/lux/data/collection/dictionary.lux index 195640d66..c4c8efeb1 100644 --- a/stdlib/source/lux/data/collection/dictionary.lux +++ b/stdlib/source/lux/data/collection/dictionary.lux @@ -4,6 +4,9 @@ [hash (#+ Hash)] [equivalence (#+ Equivalence)] [functor (#+ Functor)]] + [control + ["." try (#+ Try)] + ["." exception (#+ exception:)]] [data ["." maybe] ["." product] @@ -569,12 +572,14 @@ #.None #0 (#.Some _) #1)) +(exception: #export key-already-exists) + (def: #export (try-put key val dict) {#.doc "Only puts the KV-pair if the key is not already present."} - (All [k v] (-> k v (Dictionary k v) (Dictionary k v))) + (All [k v] (-> k v (Dictionary k v) (Try (Dictionary k v)))) (case (get key dict) - #.None (put key val dict) - (#.Some _) dict)) + #.None (#try.Success (put key val dict)) + (#.Some _) (exception.throw ..key-already-exists []))) (def: #export (update key f dict) {#.doc "Transforms the value located at key (if available), using the given function."} diff --git a/stdlib/source/lux/data/collection/row.lux b/stdlib/source/lux/data/collection/row.lux index d73f8bbf5..2b7b555be 100644 --- a/stdlib/source/lux/data/collection/row.lux +++ b/stdlib/source/lux/data/collection/row.lux @@ -10,6 +10,8 @@ [fold (#+ Fold)] [predicate (#+ Predicate)]] [control + ["." try (#+ Try)] + ["." exception (#+ exception:)] ["p" parser ["s" code (#+ Parser)]]] [data @@ -225,59 +227,71 @@ (set@ #tail (new-tail val))) ))) +(exception: incorrect-row-structure) + +(exception: #export [a] (index-out-of-bounds {row (Row a)} {index Nat}) + (exception.report ["Size" (:: n.decimal encode (get@ #size row))] + ["Index" (:: n.decimal encode index)])) + +(exception: base-was-not-found) + +(def: #export (within-bounds? row idx) + (All [a] (-> (Row a) Nat Bit)) + (and (n.>= 0 idx) + (n.< (get@ #size row) idx))) + (def: (base-for idx row) - (All [a] (-> Index (Row a) (Maybe (Base a)))) - (let [row-size (get@ #size row)] - (if (and (n.>= 0 idx) - (n.< row-size idx)) - (if (n.>= (tail-off row-size) idx) - (#.Some (get@ #tail row)) - (loop [level (get@ #level row) - hierarchy (get@ #root row)] - (case [(n.> branching-exponent level) - (array.read (branch-idx (i64.logic-right-shift level idx)) hierarchy)] - [#1 (#.Some (#Hierarchy sub))] - (recur (level-down level) sub) - - [#0 (#.Some (#Base base))] - (#.Some base) - - [_ #.None] - #.None - - _ - (error! "Incorrect row structure.")))) - #.None))) + (All [a] (-> Index (Row a) (Try (Base a)))) + (if (within-bounds? row idx) + (if (n.>= (tail-off (get@ #size row)) idx) + (#try.Success (get@ #tail row)) + (loop [level (get@ #level row) + hierarchy (get@ #root row)] + (case [(n.> branching-exponent level) + (array.read (branch-idx (i64.logic-right-shift level idx)) hierarchy)] + [#1 (#.Some (#Hierarchy sub))] + (recur (level-down level) sub) + + [#0 (#.Some (#Base base))] + (#try.Success base) + + [_ #.None] + (exception.throw ..base-was-not-found []) + + _ + (exception.throw ..incorrect-row-structure [])))) + (exception.throw ..index-out-of-bounds [row idx]))) (def: #export (nth idx row) - (All [a] (-> Nat (Row a) (Maybe a))) - (do maybe.monad + (All [a] (-> Nat (Row a) (Try a))) + (do try.monad [base (base-for idx row)] - (array.read (branch-idx idx) base))) + (case (array.read (branch-idx idx) base) + (#.Some value) + (#try.Success value) + + #.None + (exception.throw ..incorrect-row-structure [])))) (def: #export (put idx val row) - (All [a] (-> Nat a (Row a) (Row a))) + (All [a] (-> Nat a (Row a) (Try (Row a)))) (let [row-size (get@ #size row)] - (if (and (n.>= 0 idx) - (n.< row-size idx)) - (if (n.>= (tail-off row-size) idx) - (update@ #tail (`` (for {(~~ (static @.old)) - (: (-> (Base ($ 0)) (Base ($ 0))) - (|>> array.clone (array.write (branch-idx idx) val)))} - (|>> array.clone (array.write (branch-idx idx) val)))) - row) - (update@ #root (put' (get@ #level row) idx val) - row)) - row))) + (if (within-bounds? row idx) + (#try.Success (if (n.>= (tail-off row-size) idx) + (update@ #tail (`` (for {(~~ (static @.old)) + (: (-> (Base ($ 0)) (Base ($ 0))) + (|>> array.clone (array.write (branch-idx idx) val)))} + (|>> array.clone (array.write (branch-idx idx) val)))) + row) + (update@ #root (put' (get@ #level row) idx val) + row))) + (exception.throw ..index-out-of-bounds [row idx])))) (def: #export (update idx f row) - (All [a] (-> Nat (-> a a) (Row a) (Row a))) - (case (nth idx row) - (#.Some val) - (put idx (f val) row) - - #.None - row)) + (All [a] (-> Nat (-> a a) (Row a) (Try (Row a)))) + (do try.monad + [val (nth idx row)] + (put idx (f val) row))) (def: #export (pop row) (All [a] (-> (Row a) (Row a))) diff --git a/stdlib/source/lux/data/maybe.lux b/stdlib/source/lux/data/maybe.lux index 3a8bc8497..6d425011c 100644 --- a/stdlib/source/lux/data/maybe.lux +++ b/stdlib/source/lux/data/maybe.lux @@ -89,6 +89,7 @@ (macro: #export (default tokens state) {#.doc (doc "Allows you to provide a default value that will be used" "if a (Maybe x) value turns out to be #.None." + "Note: the expression for the default value will not be computed if the base computation succeeds." (default +20 (#.Some +10)) "=>" +10 |