mirror of
https://github.com/carp-lang/Carp.git
synced 2024-09-11 05:25:28 +03:00
Merge pull request #442 from GrayJack/safe-array
Make Array module safer
This commit is contained in:
commit
4f61d83730
@ -67,6 +67,7 @@ To build this example, save it to a file called 'example.carp' and load it with
|
||||
* Reini Urban
|
||||
* Jonas Granquist
|
||||
* Joel Kaasinen ([@opqdonut](https://github.com/opqdonut))
|
||||
* Eric Shimizu Karbstein ([@GrayJack](https://github.com/GrayJack))
|
||||
|
||||
Are you missing from the contributors list? Please send a pull request!
|
||||
|
||||
|
@ -41,13 +41,15 @@ It will sum the previous sum with each new value, starting at `0`.")
|
||||
(break))))
|
||||
res))
|
||||
|
||||
(doc find "finds an element in `a` that matches the function `f`.")
|
||||
(doc find "finds an element in `a` that matches the function `f` and wraps it in a `Just`.
|
||||
|
||||
If it doesn’t find an element, `Nothing` will be returned.")
|
||||
(defn find [f a]
|
||||
(let-do [res (zero)]
|
||||
(let-do [res (Maybe.Nothing)]
|
||||
(for [i 0 (length a)]
|
||||
(when (~f (nth a i))
|
||||
(do
|
||||
(set! res @(nth a i))
|
||||
(set! res (Maybe.Just @(nth a i)))
|
||||
(break))))
|
||||
res))
|
||||
|
||||
@ -108,43 +110,44 @@ Returns `Nothing` if the array is empty.")
|
||||
(defn /= [a b]
|
||||
(not (= (the (Ref (Array a)) a) b)))
|
||||
|
||||
; TODO unsafe!
|
||||
(doc maximum "gets the maximum in an array (elements must support `<`).")
|
||||
(doc maximum "gets the maximum in an array (elements must support `<`) and wraps it in a `Just`.
|
||||
|
||||
If the array is empty, it returns `Nothing`.")
|
||||
(defn maximum [xs]
|
||||
(let [result (unsafe-first xs)
|
||||
n (length xs)]
|
||||
(do
|
||||
(if (empty? xs)
|
||||
(Maybe.Nothing)
|
||||
(let-do [result (nth xs 0)
|
||||
n (length xs)]
|
||||
(for [i 1 n]
|
||||
(let [x @(nth xs i)]
|
||||
(if (< &result &x)
|
||||
(set! result x)
|
||||
())))
|
||||
result)))
|
||||
(let [x (nth xs i)]
|
||||
(when (< result x)
|
||||
(set! result x))))
|
||||
(Maybe.Just @result))))
|
||||
|
||||
; TODO unsafe!
|
||||
(doc minimum "gets the maximum in an array (elements must support `>`).")
|
||||
(doc minimum "gets the minimum in an array (elements must support `>`) and wraps it in a `Just`.
|
||||
|
||||
If the array is empty, returns `Nothing`")
|
||||
(defn minimum [xs]
|
||||
(let [result (unsafe-first xs)
|
||||
n (length xs)]
|
||||
(do
|
||||
(if (empty? xs)
|
||||
(Maybe.Nothing)
|
||||
(let-do [result (nth xs 0)
|
||||
n (length xs)]
|
||||
(for [i 1 n]
|
||||
(let [x @(nth xs i)]
|
||||
(if (> &result &x)
|
||||
(set! result x)
|
||||
())))
|
||||
result)))
|
||||
(let [x (nth xs i)]
|
||||
(when (> result x)
|
||||
(set! result x))))
|
||||
(Maybe.Just @result))))
|
||||
|
||||
(doc sum "ums an array (elements must support `+` and `zero`).")
|
||||
(doc sum "sums an array (elements must support `+` and `zero`).")
|
||||
(defn sum [xs]
|
||||
(Array.reduce &(fn [x y] (+ x @y)) (zero) xs))
|
||||
|
||||
(doc subarray "gets a subarray from `start-index` to `end-index`.")
|
||||
(defn subarray [xs start-index end-index]
|
||||
(let [result []]
|
||||
(do
|
||||
(for [i start-index end-index]
|
||||
(set! result (push-back result @(nth xs i))))
|
||||
result)))
|
||||
(let-do [result []]
|
||||
(for [i start-index end-index]
|
||||
(set! result (push-back result @(nth xs i))))
|
||||
result))
|
||||
|
||||
(doc prefix-array "gets a prefix array to `end-index`.")
|
||||
(defn prefix-array [xs end-index]
|
||||
@ -166,13 +169,15 @@ Returns `Nothing` if the array is empty.")
|
||||
(set! j (Int.dec j))))
|
||||
a))
|
||||
|
||||
(doc index-of "gets the index of element `e` in an array.")
|
||||
(doc index-of "gets the index of element `e` in an array and wraps it on a `Just`.
|
||||
|
||||
If the element is not found, returns `Nothing`")
|
||||
(defn index-of [a e]
|
||||
(let-do [idx -1]
|
||||
(let-do [idx (Maybe.Nothing)]
|
||||
(for [i 0 (length a)]
|
||||
(when (= (nth a i) e)
|
||||
(do
|
||||
(set! idx i)
|
||||
(set! idx (Maybe.Just i))
|
||||
(break))))
|
||||
idx))
|
||||
|
||||
|
@ -82,7 +82,7 @@
|
||||
(= n 1) @(Array.nth data 0)
|
||||
(let [x @(Array.nth data (/ n 2)) ; else
|
||||
l (- x (/ (from-int interval) 2.0))
|
||||
cf (Array.index-of data &x)
|
||||
cf (Maybe.from (Array.index-of data &x) -1)
|
||||
f (Array.element-count data &x)]
|
||||
(+ l (/ (* (from-int interval) (- (/ (from-int n) 2.0) (from-int cf)))
|
||||
(from-int f)))))))
|
||||
@ -177,8 +177,8 @@
|
||||
(defn summary [samples]
|
||||
(Summary.init
|
||||
(Array.sum samples)
|
||||
(Array.minimum samples)
|
||||
(Array.maximum samples)
|
||||
(Maybe.from (Array.minimum samples) 0.0)
|
||||
(Maybe.from (Array.maximum samples) 0.0)
|
||||
(mean samples)
|
||||
(median samples)
|
||||
(variance samples)
|
||||
|
@ -36,4 +36,8 @@
|
||||
(doc reverse "reverses a `Pair` `p` such that its first member is its second member and vice versa.")
|
||||
(defn reverse [p]
|
||||
(Pair.init @(Pair.b p) @(Pair.a p)))
|
||||
)
|
||||
|
||||
(doc zero "return default values of the type inside `Pair`")
|
||||
(defn zero []
|
||||
(Pair.init (zero) (zero)))
|
||||
)
|
||||
|
@ -76,21 +76,29 @@
|
||||
&(reverse [1 2 3])
|
||||
"reverse works as expected")
|
||||
(assert-equal test
|
||||
10
|
||||
(maximum &(range 1 10 1))
|
||||
&(Maybe.Just 10)
|
||||
&(maximum &(range 1 10 1))
|
||||
"maximum works as expected")
|
||||
(assert-equal test
|
||||
1
|
||||
(minimum &(range 1 10 1))
|
||||
&(Maybe.Just 1)
|
||||
&(minimum &(range 1 10 1))
|
||||
"minimum works as expected")
|
||||
(assert-equal test
|
||||
&(Pair.init 2 1)
|
||||
&(Maybe.Just (Pair.init 2 1))
|
||||
&(maximum &[(Pair.init 1 3) (Pair.init 2 1) (Pair.init 2 0)])
|
||||
"maximum works on pairs")
|
||||
(assert-equal test
|
||||
&(Pair.init 1 3)
|
||||
&(Maybe.Just (Pair.init 1 3))
|
||||
&(minimum &[(Pair.init 1 3) (Pair.init 2 1) (Pair.init 2 0)])
|
||||
"minimum works on pairs")
|
||||
(assert-equal test
|
||||
&(Maybe.Just 3)
|
||||
&(index-of &[1 2 3 4] &4)
|
||||
"index-of works as expected when element is in the array")
|
||||
(assert-equal test
|
||||
&(Maybe.Nothing)
|
||||
&(index-of &[1 2 3 4] &7)
|
||||
"index-of works as expected when element is not in the array")
|
||||
(assert-equal test
|
||||
55
|
||||
(sum &(range 1 10 1))
|
||||
@ -247,12 +255,12 @@
|
||||
(all? &(fn [x] (= 0 @x)) &(range 10 1 -1))
|
||||
"all? works as expected II")
|
||||
(assert-equal test
|
||||
3
|
||||
(find &(fn [x] (= 3 @x)) &(range 1 10 1))
|
||||
&(Maybe.Just 3)
|
||||
&(find &(fn [x] (= 3 @x)) &(range 1 10 1))
|
||||
"find works as expected I")
|
||||
(assert-equal test
|
||||
0
|
||||
(find &(fn [x] (= 0 @x)) &(range 1 10 1))
|
||||
&(Maybe.Nothing)
|
||||
&(find &(fn [x] (= 0 @x)) &(range 1 10 1))
|
||||
"find works as expected II")
|
||||
(assert-equal test
|
||||
&(Maybe.Nothing)
|
||||
|
@ -231,11 +231,11 @@
|
||||
|
||||
(defn array-maximum []
|
||||
(let [xs [1 7 2 9 3 8 4 6 5]]
|
||||
(assert (= 9 (maximum &xs)))))
|
||||
(assert (= &(Maybe.Just 9) &(maximum &xs)))))
|
||||
|
||||
(defn array-minimum []
|
||||
(let [xs [8 4 6 5 1 7 2 9 3]]
|
||||
(assert (= 1 (minimum &xs)))))
|
||||
(assert (= &(Maybe.Just 1) &(minimum &xs)))))
|
||||
|
||||
(defn array-sum []
|
||||
(let [xs [10 20 30 40 50]]
|
||||
@ -252,7 +252,7 @@
|
||||
|
||||
(defn array-index-of []
|
||||
(let [xs [@"a" @"b" @"c" @"d" @"e"]]
|
||||
(assert (= 2 (Array.index-of &xs "c")))))
|
||||
(assert (= &(Maybe.Just 2) &(Array.index-of &xs "c")))))
|
||||
|
||||
(defn array-element-count []
|
||||
(let [xs [@"a" @"b" @"a" @"a" @"b"]]
|
||||
|
Loading…
Reference in New Issue
Block a user