sumtypes: multiple fixes

- add test suite for Result
- make Array a little safer overall
- document Maybe and Result comprehensively
- rework Array documentation
This commit is contained in:
hellerve 2019-02-15 10:18:23 +01:00
parent 5254b8750a
commit e24fd38258
33 changed files with 1536 additions and 193 deletions

View File

@ -1,6 +1,15 @@
(defmodule Array
(doc reduce "Reduce an array, using the function f.")
(doc reduce "will reduce an array `xs` into a single value using a function `f` that takes the reduction thus far and the next value. The initial reduction value is `x`.
As an example, consider this definition of `sum` based on `reduce`:
```
(defn sum [x]
(reduce + 0 x))
```
It will sum the previous sum with each new value, starting at `0`.")
(defn reduce [f x xs]
(let [total x]
(do
@ -8,11 +17,11 @@
(set! total (~f total (nth xs i))))
total)))
(doc empty? "Checks whether the array is empty.")
(doc empty? "checks whether the array `a` is empty.")
(defn empty? [a]
(= (Array.length a) 0))
(doc any? "Checks whether any of the elements in `a` match the function `f`.")
(doc any? "checks whether any of the elements in `a` match the function `f`.")
(defn any? [f a]
(let-do [res false]
(for [i 0 (length a)]
@ -22,7 +31,7 @@
(break))))
res))
(doc all? "Checks whether all of the elements in `a` match the function `f`.")
(doc all? "checks whether all of the elements in `a` match the function `f`.")
(defn all? [f a]
(let-do [res true]
(for [i 0 (length a)]
@ -32,7 +41,7 @@
(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`.")
(defn find [f a]
(let-do [res (zero)]
(for [i 0 (length a)]
@ -42,25 +51,48 @@
(break))))
res))
(doc find-index "Finds the index of the first element in `a` that matches the function `f`, or -1.")
(doc find-index "finds the index of the first element in `a` that matches the function `f` and wraps it in a `Just`.
If it doesnt find an index, `Nothing` will be returned.")
(defn find-index [f a]
(let-do [ret -1]
(let-do [ret (Maybe.Nothing)]
(for [i 0 (length a)]
(when (~f (nth a i))
(do
(set! ret i)
(set! ret (Maybe.Just i))
(break))))
ret))
(doc first "Take the first element of an array.")
(defn first [a]
(doc unsafe-first "takes the first element of an array.
Generates a runtime error if the array is empty.")
(defn unsafe-first [a]
@(Array.nth a 0))
(doc last "Take the last element of an array.")
(defn last [a]
(doc first "takes the first element of an array and returns a `Just`.
Returns `Nothing` if the array is empty.")
(defn first [a]
(if (empty? a)
(Maybe.Nothing)
(Maybe.Just @(Array.nth a 0))))
(doc unsafe-last "takes the last element of an array.
Generates a runtime error if the array is empty.")
(defn unsafe-last [a]
@(Array.nth a (Int.dec (Array.length a))))
(doc = "Compare two arrays.")
(doc last "takes the last element of an array and returns a `Just`.
Returns `Nothing` if the array is empty.")
(defn last [a]
(if (empty? a)
(Maybe.Nothing)
(Maybe.Just @(Array.nth a (Int.dec (Array.length a))))))
(doc = "compares two arrays.")
(defn = [a b]
(if (/= (length a) (length b))
false
@ -72,12 +104,14 @@
(break))))
eq)))
(doc = "compares two arrays and inverts the result.")
(defn /= [a b]
(not (= (the (Ref (Array a)) a) b)))
(doc maximum "Get the maximum in an array (elements must support <).")
; TODO unsafe!
(doc maximum "gets the maximum in an array (elements must support `<`).")
(defn maximum [xs]
(let [result (first xs)
(let [result (unsafe-first xs)
n (length xs)]
(do
(for [i 1 n]
@ -87,9 +121,10 @@
())))
result)))
(doc minimum "Get the maximum in an array (elements must support >).")
; TODO unsafe!
(doc minimum "gets the maximum in an array (elements must support `>`).")
(defn minimum [xs]
(let [result (first xs)
(let [result (unsafe-first xs)
n (length xs)]
(do
(for [i 1 n]
@ -99,11 +134,11 @@
())))
result)))
(doc minimum "Sum an array (elements must support + and zero).")
(doc sum "ums an array (elements must support `+` and `zero`).")
(defn sum [xs]
(Array.reduce &(fn [x y] (+ x @y)) (zero) xs))
(doc subarray "Get subarray from start-index to end-index.")
(doc subarray "gets a subarray from `start-index` to `end-index`.")
(defn subarray [xs start-index end-index]
(let [result []]
(do
@ -111,15 +146,15 @@
(set! result (push-back result @(nth xs i))))
result)))
(doc prefix-array "Get prefix-array to end-index.")
(doc prefix-array "gets a prefix array to `end-index`.")
(defn prefix-array [xs end-index]
(subarray xs 0 end-index))
(doc suffix-array "Get subarray from start-index.")
(doc suffix-array "gets a suffix array from `start-index`.")
(defn suffix-array [xs start-index]
(subarray xs start-index (length xs)))
(doc reverse "Reverse an array.")
(doc reverse "reverses an array.")
(defn reverse [a]
(let-do [i 0
j (Int.dec (length &a))]
@ -131,7 +166,7 @@
(set! j (Int.dec j))))
a))
(doc index-of "Get the index of element e in an array.")
(doc index-of "gets the index of element `e` in an array.")
(defn index-of [a e]
(let-do [idx -1]
(for [i 0 (length a)]
@ -141,14 +176,14 @@
(break))))
idx))
(doc element-count "Count occurrences of element e in an array.")
(doc element-count "counts the occurrences of element `e` in an array.")
(defn element-count [a e]
(let-do [c 0]
(for [i 0 (length a)]
(when (= e (nth a i)) (set! c (Int.inc c))))
c))
(doc predicate-count "Count number of elements satisfying predicate in an array.")
(doc predicate-count "counts the number of elements satisfying the predicate function `pred` in an array.")
(defn predicate-count [a pred]
(let-do [c 0]
(for [i 0 (length a)]
@ -156,22 +191,22 @@
(set! c (Int.inc c))))
c))
(doc aupdate "Transmute the element at index i of array a using function f.")
(doc aupdate "transmutes (i.e. updates) the element at index `i` of an array `a` using the function `f`.")
(defn aupdate [a i f]
(let [new-value (~f (nth &a i))]
(aset a i new-value)))
(doc aupdate! "Transmute the element at index i of array a using function f in place.")
(doc aupdate! "transmutes (i.e. updates) the element at index `i` of an array `a` using the function `f` in place.")
(defn aupdate! [a i f]
(aset! a i (~f (nth a i))))
(doc swap "Swap indices i and j of array a.")
(doc swap "swaps the indices `i` and `j` of an array `a`.")
(defn swap [a i j]
(let [x @(nth &a i)
y @(nth &a j)]
(aset (aset a i y) j x)))
(doc swap! "Swap indices i and j of array a in place.")
(doc swap! "swaps the indices `i` and `j` of an array `a` in place.")
(defn swap! [a i j]
(let-do [x @(nth a i)
y @(nth a j)]
@ -179,7 +214,7 @@
(aset! a j x)))
; cannot use for, because we want also be able to go downwards
(doc range "Create an array from start to end with step between them (the elements must support <, <=, and >=).")
(doc range "creates an array from `start` to `end` with `step` between them (the elements must support `<`, `<=`, and `>=`).")
(defn range [start end step]
(let-do [x (allocate (Int.inc (Int.abs (/ (- end start) step))))
e start
@ -192,32 +227,38 @@
(set! e (+ e step))))
x))
(doc repeat "Repeat function f n times and store the results in an array.")
(doc repeat "repeats the function `f` `n` times and stores the results in an array.")
(defn repeat [n f]
(let-do [a (allocate n)]
(for [i 0 n] (aset-uninitialized! &a i (~f)))
a))
(doc repeat-indexed "Repeat function f n times and store the results in an array (will be supplied with the index).")
(doc repeat-indexed "repeats function `f` `n `times and stores the results in an array.
This is similar to [`repeat`](#repeat), but the function `f` will be supplied with the index of the element.")
(defn repeat-indexed [n f]
(let-do [a (allocate n)]
(for [i 0 n] (aset-uninitialized! &a i (f i)))
a))
(doc replicate "Repeat element e n times and store the results in an array.")
(doc replicate "repeats element `e` `n` times and stores the results in an array.")
(defn replicate [n e]
(let-do [a (allocate n)]
(for [i 0 n] (aset-uninitialized! &a i @e))
a))
(doc copy-map "Map over array a using function f (copies the array).")
(doc copy-map "maps over an array `a` using the function `f`.
This function copies the array. If you dont want that, use [`endo-map`](#endo-map).")
(defn copy-map [f a]
(let-do [na (allocate (length a))]
(for [i 0 (length a)]
(aset-uninitialized! &na i (~f (nth a i))))
na))
(doc zip "Map over two arrays using a function that takes two arguments. Produces a new array with the length of the shorter input.")
(doc zip "maps over two arrays using a function `f` that takes two arguments. It will produces a new array with the length of the shorter input.
The trailing elements of the longer array will be discarded.")
(defn zip [f a b]
(let-do [l (Int.min (length a) (length b))
na (allocate l)]
@ -225,7 +266,7 @@
(aset-uninitialized! &na i (~f (nth a i) (nth b i))))
na))
(doc sum-length "Returns the sum of lengths from an Array of Arrays.")
(doc sum-length "returns the sum of lengths from a nested array `xs`.")
(defn sum-length [xs]
(let-do [sum 0
lxs (Array.length xs)]
@ -233,10 +274,10 @@
(set! sum (+ sum (Array.length (Array.nth xs i)))))
sum))
(doc zero "Returns the empty array.")
(doc zero "returns the empty array.")
(defn zero [] [])
(doc concat "Returns a new Array which is the concatenation of the provided `xs`.")
(doc concat "returns a new array which is the concatenation of the provided nested array `xs`.")
(defn concat [xs]
;; This is using a StringBuilder pattern to only perform one allocation and
;; to only copy each of the incoming Array(s) once.
@ -253,18 +294,18 @@
(set! j (+ j len))))
result))
(doc enumerated "Create a new array of Pair:s where the first position is the index and the second position is the element from the original array.")
(doc enumerated "creates a new array of `Pair`s where the first position is the index and the second position is the element from the original array `xs`.")
(defn enumerated [xs]
(zip &Pair.init-from-refs
&(range 0 (length xs) 1) ;; Inefficient, creates a temporary array.
xs))
(doc remove "Remove occurrences of element el in array arr, in-place")
(doc remove "removes all occurrences of the element `el` in the array `arr`, in place.")
(defn remove [el arr]
(endo-filter &(fn [x] (not (= el x)))
arr))
(doc remove-nth "Remove element at index idx from arr")
(doc remove-nth "removes element at index `idx` from the array `arr`.")
(defn remove-nth [i arr]
(do
;;(assert (<= 0 i))
@ -273,6 +314,8 @@
(aset! &arr j @(nth &arr (inc j))))
(pop-back arr)))
(doc copy-filter "Filter elements in an array, creates a copy.")
(doc copy-filter "filters the elements in an array.
It will create a copy. If you want to avoid that, consider using [`endo-filter`](#endo-filter) instead.")
(defn copy-filter [f a] (endo-filter f @a))
)

View File

@ -3,30 +3,40 @@
(Nothing []))
(defmodule Maybe
(doc apply "applies a function to the value inside `a` if it is a `Just`, and wraps it up again. If it is `Nothing`, it is just returned.")
(defn apply [a f]
(match a
(Nothing) (Nothing)
(Just x) (Just (f x))))
(doc unsafe-from "is an unsafe unwrapper that will get the value from a `Just`. If `a` is `Nothing`, a runtime error will be generated.")
(defn unsafe-from [a]
(match a
(Just x) x))
(doc from "is an unwrapper that will get the value from a `Just`, or a default value if a `Nothing` is passed.")
(defn from [a dflt]
(match a
(Nothing) dflt
(Just x) x))
(doc just? "checks whether the given value `a` is a `Just`.
It is the inverse of [`nothing?`](#nothing?).")
(defn just? [a]
(match @a
(Nothing) false
(Just x) true))
(doc nothing? "checks whether the given value `a` is a `Nothing`.
It is the inverse of [`just?`](#just?).")
(defn nothing? [a]
(match @a
(Nothing) true
(Just x) false))
(doc = "equality is defined as the equality of both the constructor and the contained value, i.e. `(Just 1)` and `(Just 1)` are the same, but `(Just 1)` and `(Just 2)` are not.")
(defn = [a b]
(match @a
(Nothing) (nothing? b)

View File

@ -3,79 +3,93 @@
(Error [b]))
(defmodule Result
(doc apply "takes a `Result` `a` and applies functions to them, one in the case that it is an `Error`, one in the case that it is a `Success`.")
(defn apply [a success-f error-f]
(match a
(Success x) (success-f x)
(Error x) (error-f x)))
(Success x) (Success (success-f x))
(Error x) (Error (error-f x))))
(doc map "takes a `Result` and applies a function `f` to it if it is a `Success` type, and wraps it back up. In the case that it is an `Error`, it is returned as is.")
(defn map [a f]
(match a
(Success x) (Success (f x))
(Error x) (Error x)))
(doc and-then "takes a `Result` and applies a function `f` to it if it is a `Success` type. In the case that it is an `Error`, it is returned as is.
It is thus quite similar to [`map`](#map), but it will unwrap the value.")
(defn and-then [a f]
(match a
(Success x) (f x)
(Error x) (Error x)))
(doc unwrap-or-zero "takes a `Result` and either unwraps it if it is a `Success`, or calls `zero`. `zero` must be defined on the `Success` type.")
(defn unwrap-or-zero [a]
(match a
(Success x) x
(Error _) (zero)))
;(defn and [a b]
; (match a
; (Success _) b
; (Error x) (Error x)))
;(defn or [a b]
; (match a
; (Success x) (Success x)
; (Error _) b))
(doc or-else "takes a `Result` and applies a function `f` to it if it is an `Error` type. In the case that it is a `Success`, it is returned as is.
It is the inverse of [`and-then`](#and-then).")
(defn or-else [a f]
(match a
(Success x) (Success x)
(Error x) (f x)))
(doc unwrap-or-else "takes a `Result` and either unwraps it if it is a `Success`, or calls a function `f` on the value contained in the `Error`.")
(defn unwrap-or-else [a f]
(match a
(Success x) x
(Error x) (f x)))
(doc unsafe-from-success "is an unsafe unwrapper that will get the value from a `Success`. If `a` is an `Error`, a runtime error will be generated.")
(defn unsafe-from-success [a]
(match a
(Success x) x))
(doc from-success "is an unwrapper that will get the value from a `Success`. If `a` is an `Error`, a default value will be returned.")
(defn from-success [a dflt]
(match a
(Error _) dflt
(Success x) x))
(doc unsafe-from-error "is an unsafe unwrapper that will get the value from an `Error`. If `a` is a `Success`, a runtime error will be generated.")
(defn unsafe-from-error [a]
(match a
(Error x) x))
(doc from-error "is an unwrapper that will get the value from an `Error`. If `a` is a `Success`, a default value will be returned.")
(defn from-error [a dflt]
(match a
(Success _) dflt
(Error x) x))
(doc to-maybe "is a function that will convert a `Result` to a `Maybe`, where a `Success` becomes a `Just` and an `Error` becomes a `Nothing`.
The error value is thrown away.")
(defn to-maybe [a]
(match a
(Success x) (Maybe.Just x)
(Error _) (Maybe.Nothing)))
(doc success? "checks whether the given value `a` is a `Success`.
It is the inverse of [`error?`](#error?).")
(defn success? [a]
(match @a
(Error _) false
(Success _) true))
(doc success? "checks whether the given value `a` is an `Error`.
It is the inverse of [`success?`](#success?).")
(defn error? [a]
(match @a
(Error _) true
(Success _) false))
(doc = "equality is defined as the equality of both the constructor and the contained value, i.e. `(Success 1)` and `(Success 1)` are the same, but `(Success 1)` and `(Success 2)` are not.")
(defn = [a b]
(match @a
(Success x)
@ -87,3 +101,13 @@
(Success _) false
(Error y) (= x y))))
)
(defmodule Maybe
(doc to-result "is a function that will convert a `Maybe` to a `Result`, where a `Just` becomes a `Success` and a `Nothing` becomes an `Error`.
Youll also nee to provide an error message `error` that is given to the `Error` constructor if necessary.")
(defn to-result [a error]
(match a
(Nothing) (Result.Error error)
(Just x) (Result.Success x)))
)

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>
@ -163,7 +173,7 @@
(= a b)
</pre>
<p class="doc">
<p>Compare two arrays.</p>
<p>compares two arrays and inverts the result.</p>
</p>
</div>
@ -183,7 +193,7 @@
(all? f a)
</pre>
<p class="doc">
<p>Checks whether all of the elements in <code>a</code> match the function <code>f</code>.</p>
<p>checks whether all of the elements in <code>a</code> match the function <code>f</code>.</p>
</p>
</div>
@ -222,7 +232,7 @@
(any? f a)
</pre>
<p class="doc">
<p>Checks whether any of the elements in <code>a</code> match the function <code>f</code>.</p>
<p>checks whether any of the elements in <code>a</code> match the function <code>f</code>.</p>
</p>
</div>
@ -299,7 +309,7 @@
(aupdate a i f)
</pre>
<p class="doc">
<p>Transmute the element at index i of array a using function f.</p>
<p>transmutes (i.e. updates) the element at index <code>i</code> of an array <code>a</code> using the function <code>f</code>.</p>
</p>
</div>
@ -319,7 +329,7 @@
(aupdate! a i f)
</pre>
<p class="doc">
<p>Transmute the element at index i of array a using function f in place.</p>
<p>transmutes (i.e. updates) the element at index <code>i</code> of an array <code>a</code> using the function <code>f</code> in place.</p>
</p>
</div>
@ -339,7 +349,7 @@
(concat xs)
</pre>
<p class="doc">
<p>Returns a new Array which is the concatenation of the provided <code>xs</code>.</p>
<p>returns a new array which is the concatenation of the provided nested array <code>xs</code>.</p>
</p>
</div>
@ -378,7 +388,8 @@
(copy-filter f a)
</pre>
<p class="doc">
<p>Filter elements in an array, creates a copy.</p>
<p>filters the elements in an array.</p>
<p>It will create a copy. If you want to avoid that, consider using <a href="#endo-filter"><code>endo-filter</code></a> instead.</p>
</p>
</div>
@ -398,7 +409,8 @@
(copy-map f a)
</pre>
<p class="doc">
<p>Map over array a using function f (copies the array).</p>
<p>maps over an array <code>a</code> using the function <code>f</code>.</p>
<p>This function copies the array. If you dont want that, use <a href="#endo-map"><code>endo-map</code></a>.</p>
</p>
</div>
@ -437,7 +449,7 @@
(element-count a e)
</pre>
<p class="doc">
<p>Count occurrences of element e in an array.</p>
<p>counts the occurrences of element <code>e</code> in an array.</p>
</p>
</div>
@ -457,7 +469,7 @@
(empty? a)
</pre>
<p class="doc">
<p>Checks whether the array is empty.</p>
<p>checks whether the array <code>a</code> is empty.</p>
</p>
</div>
@ -515,7 +527,7 @@
(enumerated xs)
</pre>
<p class="doc">
<p>Create a new array of Pair:s where the first position is the index and the second position is the element from the original array.</p>
<p>creates a new array of <code>Pair</code>s where the first position is the index and the second position is the element from the original array <code>xs</code>.</p>
</p>
</div>
@ -535,7 +547,7 @@
(find f a)
</pre>
<p class="doc">
<p>Finds an element in <code>a</code> that matches the function <code>f</code>.</p>
<p>finds an element in <code>a</code> that matches the function <code>f</code>.</p>
</p>
</div>
@ -549,13 +561,14 @@
defn
</div>
<p class="sig">
(λ [(Ref (λ [&amp;a] Bool)), (Ref (Array a))] Int)
(λ [(Ref (λ [&amp;a] Bool)), (Ref (Array a))] (Maybe Int))
</p>
<pre class="args">
(find-index f a)
</pre>
<p class="doc">
<p>Finds the index of the first element in <code>a</code> that matches the function <code>f</code>, or -1.</p>
<p>finds the index of the first element in <code>a</code> that matches the function <code>f</code> and wraps it in a <code>Just</code>.</p>
<p>If it doesnt find an index, <code>Nothing</code> will be returned.</p>
</p>
</div>
@ -569,13 +582,14 @@
defn
</div>
<p class="sig">
(λ [(Ref (Array a))] a)
(λ [(Ref (Array a))] (Maybe a))
</p>
<pre class="args">
(first a)
</pre>
<p class="doc">
<p>Take the first element of an array.</p>
<p>takes the first element of an array and returns a <code>Just</code>.</p>
<p>Returns <code>Nothing</code> if the array is empty.</p>
</p>
</div>
@ -595,7 +609,7 @@
(index-of a e)
</pre>
<p class="doc">
<p>Get the index of element e in an array.</p>
<p>gets the index of element <code>e</code> in an array.</p>
</p>
</div>
@ -609,13 +623,14 @@
defn
</div>
<p class="sig">
(λ [(Ref (Array a))] a)
(λ [(Ref (Array a))] (Maybe a))
</p>
<pre class="args">
(last a)
</pre>
<p class="doc">
<p>Take the last element of an array.</p>
<p>takes the last element of an array and returns a <code>Just</code>.</p>
<p>Returns <code>Nothing</code> if the array is empty.</p>
</p>
</div>
@ -654,7 +669,7 @@
(maximum xs)
</pre>
<p class="doc">
<p>Get the maximum in an array (elements must support &lt;).</p>
<p>gets the maximum in an array (elements must support <code>&lt;</code>).</p>
</p>
</div>
@ -674,7 +689,7 @@
(minimum xs)
</pre>
<p class="doc">
<p>Sum an array (elements must support + and zero).</p>
<p>gets the maximum in an array (elements must support <code>&gt;</code>).</p>
</p>
</div>
@ -751,7 +766,7 @@
(predicate-count a pred)
</pre>
<p class="doc">
<p>Count number of elements satisfying predicate in an array.</p>
<p>counts the number of elements satisfying the predicate function <code>pred</code> in an array.</p>
</p>
</div>
@ -771,7 +786,7 @@
(prefix-array xs end-index)
</pre>
<p class="doc">
<p>Get prefix-array to end-index.</p>
<p>gets a prefix array to <code>end-index</code>.</p>
</p>
</div>
@ -848,7 +863,7 @@
(range start end step)
</pre>
<p class="doc">
<p>Create an array from start to end with step between them (the elements must support &lt;, &lt;=, and &gt;=).</p>
<p>creates an array from <code>start</code> to <code>end</code> with <code>step</code> between them (the elements must support <code>&lt;</code>, <code>&lt;=</code>, and <code>&gt;=</code>).</p>
</p>
</div>
@ -887,7 +902,12 @@
(reduce f x xs)
</pre>
<p class="doc">
<p>Reduce an array, using the function f.</p>
<p>will reduce an array <code>xs</code> into a single value using a function <code>f</code> that takes the reduction thus far and the next value. The initial reduction value is <code>x</code>.</p>
<p>As an example, consider this definition of <code>sum</code> based on <code>reduce</code>:</p>
<pre><code>(defn sum [x]
(reduce + 0 x))
</code></pre>
<p>It will sum the previous sum with each new value, starting at <code>0</code>.</p>
</p>
</div>
@ -907,7 +927,7 @@
(remove el arr)
</pre>
<p class="doc">
<p>Remove occurrences of element el in array arr, in-place</p>
<p>removes all occurrences of the element <code>el</code> in the array <code>arr</code>, in place.</p>
</p>
</div>
@ -927,7 +947,7 @@
(remove-nth i arr)
</pre>
<p class="doc">
<p>Remove element at index idx from arr</p>
<p>removes element at index <code>idx</code> from the array <code>arr</code>.</p>
</p>
</div>
@ -947,7 +967,7 @@
(repeat n f)
</pre>
<p class="doc">
<p>Repeat function f n times and store the results in an array.</p>
<p>repeats the function <code>f</code> <code>n</code> times and stores the results in an array.</p>
</p>
</div>
@ -967,7 +987,8 @@
(repeat-indexed n f)
</pre>
<p class="doc">
<p>Repeat function f n times and store the results in an array (will be supplied with the index).</p>
<p>repeats function <code>f</code> <code>n</code>times and stores the results in an array.</p>
<p>This is similar to <a href="#repeat"><code>repeat</code></a>, but the function <code>f</code> will be supplied with the index of the element.</p>
</p>
</div>
@ -987,7 +1008,7 @@
(replicate n e)
</pre>
<p class="doc">
<p>Repeat element e n times and store the results in an array.</p>
<p>repeats element <code>e</code> <code>n</code> times and stores the results in an array.</p>
</p>
</div>
@ -1007,7 +1028,7 @@
(reverse a)
</pre>
<p class="doc">
<p>Reverse an array.</p>
<p>reverses an array.</p>
</p>
</div>
@ -1166,7 +1187,7 @@
(subarray xs start-index end-index)
</pre>
<p class="doc">
<p>Get subarray from start-index to end-index.</p>
<p>gets a subarray from <code>start-index</code> to <code>end-index</code>.</p>
</p>
</div>
@ -1186,7 +1207,7 @@
(suffix-array xs start-index)
</pre>
<p class="doc">
<p>Get subarray from start-index.</p>
<p>gets a suffix array from <code>start-index</code>.</p>
</p>
</div>
@ -1206,7 +1227,8 @@
(sum xs)
</pre>
<p class="doc">
<p>ums an array (elements must support <code>+</code> and <code>zero</code>).</p>
</p>
</div>
<div class="binder">
@ -1225,7 +1247,7 @@
(sum-length xs)
</pre>
<p class="doc">
<p>Returns the sum of lengths from an Array of Arrays.</p>
<p>returns the sum of lengths from a nested array <code>xs</code>.</p>
</p>
</div>
@ -1245,7 +1267,7 @@
(swap a i j)
</pre>
<p class="doc">
<p>Swap indices i and j of array a.</p>
<p>swaps the indices <code>i</code> and <code>j</code> of an array <code>a</code>.</p>
</p>
</div>
@ -1265,7 +1287,49 @@
(swap! a i j)
</pre>
<p class="doc">
<p>Swap indices i and j of array a in place.</p>
<p>swaps the indices <code>i</code> and <code>j</code> of an array <code>a</code> in place.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#unsafe-first">
<h3 id="unsafe-first">
unsafe-first
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ref (Array a))] a)
</p>
<pre class="args">
(unsafe-first a)
</pre>
<p class="doc">
<p>takes the first element of an array.</p>
<p>Generates a runtime error if the array is empty.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#unsafe-last">
<h3 id="unsafe-last">
unsafe-last
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ref (Array a))] a)
</p>
<pre class="args">
(unsafe-last a)
</pre>
<p class="doc">
<p>takes the last element of an array.</p>
<p>Generates a runtime error if the array is empty.</p>
</p>
</div>
@ -1285,7 +1349,7 @@
(zero)
</pre>
<p class="doc">
<p>Returns the empty array.</p>
<p>returns the empty array.</p>
</p>
</div>
@ -1305,7 +1369,8 @@
(zip f a b)
</pre>
<p class="doc">
<p>Map over two arrays using a function that takes two arguments. Produces a new array with the length of the shorter input.</p>
<p>maps over two arrays using a function <code>f</code> that takes two arguments. It will produces a new array with the length of the shorter input.</p>
<p>The trailing elements of the longer array will be discarded.</p>
</p>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

400
docs/core/Maybe.html Normal file
View File

@ -0,0 +1,400 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="carp_style.css">
</head>
<body>
<div class="content">
<div class="logo">
<a href="http://github.com/carp-lang/Carp">
<img src="logo.png">
</a>
<div class="title">
core
</div>
<div class="index">
<ul>
<li>
<a href="Dynamic.html">
Dynamic
</a>
</li>
<li>
<a href="Int.html">
Int
</a>
</li>
<li>
<a href="Long.html">
Long
</a>
</li>
<li>
<a href="Bool.html">
Bool
</a>
</li>
<li>
<a href="Float.html">
Float
</a>
</li>
<li>
<a href="Double.html">
Double
</a>
</li>
<li>
<a href="Vector2.html">
Vector2
</a>
</li>
<li>
<a href="Vector3.html">
Vector3
</a>
</li>
<li>
<a href="VectorN.html">
VectorN
</a>
</li>
<li>
<a href="Geometry.html">
Geometry
</a>
</li>
<li>
<a href="Statistics.html">
Statistics
</a>
</li>
<li>
<a href="String.html">
String
</a>
</li>
<li>
<a href="Char.html">
Char
</a>
</li>
<li>
<a href="Pattern.html">
Pattern
</a>
</li>
<li>
<a href="Array.html">
Array
</a>
</li>
<li>
<a href="IO.html">
IO
</a>
</li>
<li>
<a href="System.html">
System
</a>
</li>
<li>
<a href="Debug.html">
Debug
</a>
</li>
<li>
<a href="Test.html">
Test
</a>
</li>
<li>
<a href="Bench.html">
Bench
</a>
</li>
<li>
<a href="Map.html">
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>
<h1>
Maybe
</h1>
<div class="binder">
<a class="anchor" href="#=">
<h3 id="=">
=
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ref (Maybe a)), (Ref (Maybe a))] Bool)
</p>
<pre class="args">
(= a b)
</pre>
<p class="doc">
<p>equality is defined as the equality of both the constructor and the contained value, i.e. <code>(Just 1)</code> and <code>(Just 1)</code> are the same, but <code>(Just 1)</code> and <code>(Just 2)</code> are not.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#Just">
<h3 id="Just">
Just
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [a] (Maybe a))
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#Nothing">
<h3 id="Nothing">
Nothing
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [] (Maybe a))
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#apply">
<h3 id="apply">
apply
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Maybe a), (λ [a] b)] (Maybe b))
</p>
<pre class="args">
(apply a f)
</pre>
<p class="doc">
<p>applies a function to the value inside <code>a</code> if it is a <code>Just</code>, and wraps it up again. If it is <code>Nothing</code>, it is just returned.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#copy">
<h3 id="copy">
copy
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ref (Maybe a))] (Maybe a))
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#delete">
<h3 id="delete">
delete
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Maybe a)] ())
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#from">
<h3 id="from">
from
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Maybe a), a] a)
</p>
<pre class="args">
(from a dflt)
</pre>
<p class="doc">
<p>is an unwrapper that will get the value from a <code>Just</code>, or a default value if a <code>Nothing</code> is passed.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#just?">
<h3 id="just?">
just?
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ref (Maybe a))] Bool)
</p>
<pre class="args">
(just? a)
</pre>
<p class="doc">
<p>checks whether the given value <code>a</code> is a <code>Just</code>.</p>
<p>It is the inverse of <a href="#nothing?"><code>nothing?</code></a>.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#nothing?">
<h3 id="nothing?">
nothing?
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ref (Maybe a))] Bool)
</p>
<pre class="args">
(nothing? a)
</pre>
<p class="doc">
<p>checks whether the given value <code>a</code> is a <code>Nothing</code>.</p>
<p>It is the inverse of <a href="#just?"><code>just?</code></a>.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#prn">
<h3 id="prn">
prn
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ref (Maybe a))] String)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#str">
<h3 id="str">
str
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ref (Maybe a))] String)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#to-result">
<h3 id="to-result">
to-result
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Maybe a), b] (Result a b))
</p>
<pre class="args">
(to-result a error)
</pre>
<p class="doc">
<p>is a function that will convert a <code>Maybe</code> to a <code>Result</code>, where a <code>Just</code> becomes a <code>Success</code> and a <code>Nothing</code> becomes an <code>Error</code>.</p>
<p>Youll also nee to provide an error message <code>error</code> that is given to the <code>Error</code> constructor if necessary.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#unsafe-from">
<h3 id="unsafe-from">
unsafe-from
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Maybe a)] a)
</p>
<pre class="args">
(unsafe-from a)
</pre>
<p class="doc">
<p>is an unsafe unwrapper that will get the value from a <code>Just</code>. If <code>a</code> is <code>Nothing</code>, a runtime error will be generated.</p>
</p>
</div>
</div>
</body>
</html>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

540
docs/core/Result.html Normal file
View File

@ -0,0 +1,540 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="carp_style.css">
</head>
<body>
<div class="content">
<div class="logo">
<a href="http://github.com/carp-lang/Carp">
<img src="logo.png">
</a>
<div class="title">
core
</div>
<div class="index">
<ul>
<li>
<a href="Dynamic.html">
Dynamic
</a>
</li>
<li>
<a href="Int.html">
Int
</a>
</li>
<li>
<a href="Long.html">
Long
</a>
</li>
<li>
<a href="Bool.html">
Bool
</a>
</li>
<li>
<a href="Float.html">
Float
</a>
</li>
<li>
<a href="Double.html">
Double
</a>
</li>
<li>
<a href="Vector2.html">
Vector2
</a>
</li>
<li>
<a href="Vector3.html">
Vector3
</a>
</li>
<li>
<a href="VectorN.html">
VectorN
</a>
</li>
<li>
<a href="Geometry.html">
Geometry
</a>
</li>
<li>
<a href="Statistics.html">
Statistics
</a>
</li>
<li>
<a href="String.html">
String
</a>
</li>
<li>
<a href="Char.html">
Char
</a>
</li>
<li>
<a href="Pattern.html">
Pattern
</a>
</li>
<li>
<a href="Array.html">
Array
</a>
</li>
<li>
<a href="IO.html">
IO
</a>
</li>
<li>
<a href="System.html">
System
</a>
</li>
<li>
<a href="Debug.html">
Debug
</a>
</li>
<li>
<a href="Test.html">
Test
</a>
</li>
<li>
<a href="Bench.html">
Bench
</a>
</li>
<li>
<a href="Map.html">
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>
<h1>
Result
</h1>
<div class="binder">
<a class="anchor" href="#=">
<h3 id="=">
=
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ref (Result a b)), (Ref (Result a b))] Bool)
</p>
<pre class="args">
(= a b)
</pre>
<p class="doc">
<p>equality is defined as the equality of both the constructor and the contained value, i.e. <code>(Success 1)</code> and <code>(Success 1)</code> are the same, but <code>(Success 1)</code> and <code>(Success 2)</code> are not.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#Error">
<h3 id="Error">
Error
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [b] (Result a b))
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#Success">
<h3 id="Success">
Success
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [a] (Result a b))
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#and-then">
<h3 id="and-then">
and-then
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Result a b), (λ [a] (Result c b))] (Result c b))
</p>
<pre class="args">
(and-then a f)
</pre>
<p class="doc">
<p>takes a <code>Result</code> and applies a function <code>f</code> to it if it is a <code>Success</code> type. In the case that it is an <code>Error</code>, it is returned as is.</p>
<p>It is thus quite similar to <a href="#map"><code>map</code></a>, but it will unwrap the value.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#apply">
<h3 id="apply">
apply
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Result a b), (λ [a] c), (λ [b] d)] (Result c d))
</p>
<pre class="args">
(apply a success-f error-f)
</pre>
<p class="doc">
<p>takes a <code>Result</code> <code>a</code> and applies functions to them, one in the case that it is an <code>Error</code>, one in the case that it is a <code>Success</code>.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#copy">
<h3 id="copy">
copy
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ref (Result a b))] (Result a b))
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#delete">
<h3 id="delete">
delete
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Result a b)] ())
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#error?">
<h3 id="error?">
error?
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ref (Result a b))] Bool)
</p>
<pre class="args">
(error? a)
</pre>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#from-error">
<h3 id="from-error">
from-error
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Result a b), b] b)
</p>
<pre class="args">
(from-error a dflt)
</pre>
<p class="doc">
<p>is an unwrapper that will get the value from an <code>Error</code>. If <code>a</code> is a <code>Success</code>, a default value will be returned.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#from-success">
<h3 id="from-success">
from-success
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Result a b), a] a)
</p>
<pre class="args">
(from-success a dflt)
</pre>
<p class="doc">
<p>is an unwrapper that will get the value from a <code>Success</code>. If <code>a</code> is an <code>Error</code>, a default value will be returned.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#map">
<h3 id="map">
map
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Result a b), (λ [a] c)] (Result c b))
</p>
<pre class="args">
(map a f)
</pre>
<p class="doc">
<p>takes a <code>Result</code> and applies a function <code>f</code> to it if it is a <code>Success</code> type, and wraps it back up. In the case that it is an <code>Error</code>, it is returned as is.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#or-else">
<h3 id="or-else">
or-else
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Result a b), (λ [b] (Result a c))] (Result a c))
</p>
<pre class="args">
(or-else a f)
</pre>
<p class="doc">
<p>takes a <code>Result</code> and applies a function <code>f</code> to it if it is an <code>Error</code> type. In the case that it is a <code>Success</code>, it is returned as is.</p>
<p>It is the inverse of <a href="#and-then"><code>and-then</code></a>.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#prn">
<h3 id="prn">
prn
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ref (Result a b))] String)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#str">
<h3 id="str">
str
</h3>
</a>
<div class="description">
template
</div>
<p class="sig">
(λ [(Ref (Result a b))] String)
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder">
<a class="anchor" href="#success?">
<h3 id="success?">
success?
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Ref (Result a b))] Bool)
</p>
<pre class="args">
(success? a)
</pre>
<p class="doc">
<p>checks whether the given value <code>a</code> is an <code>Error</code>.</p>
<p>It is the inverse of <a href="#success?"><code>success?</code></a>.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#to-maybe">
<h3 id="to-maybe">
to-maybe
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Result a b)] (Maybe a))
</p>
<pre class="args">
(to-maybe a)
</pre>
<p class="doc">
<p>is a function that will convert a <code>Result</code> to a <code>Maybe</code>, where a <code>Success</code> becomes a <code>Just</code> and an <code>Error</code> becomes a <code>Nothing</code>.</p>
<p>The error value is thrown away.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#unsafe-from-error">
<h3 id="unsafe-from-error">
unsafe-from-error
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Result a b)] b)
</p>
<pre class="args">
(unsafe-from-error a)
</pre>
<p class="doc">
<p>is an unsafe unwrapper that will get the value from an <code>Error</code>. If <code>a</code> is a <code>Success</code>, a runtime error will be generated.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#unsafe-from-success">
<h3 id="unsafe-from-success">
unsafe-from-success
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Result a b)] a)
</p>
<pre class="args">
(unsafe-from-success a)
</pre>
<p class="doc">
<p>is an unsafe unwrapper that will get the value from a <code>Success</code>. If <code>a</code> is an <code>Error</code>, a runtime error will be generated.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#unwrap-or-else">
<h3 id="unwrap-or-else">
unwrap-or-else
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Result a b), (λ [b] a)] a)
</p>
<pre class="args">
(unwrap-or-else a f)
</pre>
<p class="doc">
<p>takes a <code>Result</code> and either unwraps it if it is a <code>Success</code>, or calls a function <code>f</code> on the value contained in the <code>Error</code>.</p>
</p>
</div>
<div class="binder">
<a class="anchor" href="#unwrap-or-zero">
<h3 id="unwrap-or-zero">
unwrap-or-zero
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(λ [(Result a b)] a)
</p>
<pre class="args">
(unwrap-or-zero a)
</pre>
<p class="doc">
<p>takes a <code>Result</code> and either unwraps it if it is a <code>Success</code>, or calls <code>zero</code>. <code>zero</code> must be defined on the <code>Success</code> type.</p>
</p>
</div>
</div>
</body>
</html>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -122,6 +122,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -118,6 +118,16 @@
Map
</a>
</li>
<li>
<a href="Maybe.html">
Maybe
</a>
</li>
<li>
<a href="Result.html">
Result
</a>
</li>
</ul>
</div>
</div>

View File

@ -32,4 +32,6 @@
Test
Bench
Map
Maybe
Result
)

View File

@ -110,7 +110,7 @@
(defn grow [snake]
(let [new-snake (Snake.update-freeze snake &inc2)
b (Snake.body &new-snake)]
(Snake.set-body new-snake (push-back @b (last b)))))
(Snake.set-body new-snake (push-back @b (unsafe-last b)))))
(defn update-after-kill [world]
(let [s (World.snake &world)
@ -121,7 +121,7 @@
(let [s (World.snake world)
h (World.human world)
b (Snake.body s)
head &(first b)]
head &(unsafe-first b)]
(if (= head h)
(update-after-kill @world)
@world)))
@ -129,7 +129,7 @@
(defn check-world [world]
(let [snake (World.snake world)
b (Snake.body snake)
head &(first b)
head &(unsafe-first b)
x @(Vector2.x head)
y @(Vector2.y head)]
(World.set-dead @world (or (< x 0.0)

View File

@ -49,12 +49,28 @@
"repeat-indexed works as expected")
(assert-equal test
1
(first &[1 2 3])
(unsafe-first &[1 2 3])
"unsafe-first works as expected")
(assert-equal test
&(Maybe.Just 1)
&(first &[1 2 3])
"first works as expected")
(assert-equal test
&(the (Maybe Int) (Maybe.Nothing))
&(first &[])
"first works as expected on empty array")
(assert-equal test
\c
(last &[\a \b \c])
(unsafe-last &[\a \b \c])
"unsafe-last works as expected")
(assert-equal test
&(Maybe.Just \c)
&(last &[\a \b \c])
"last works as expected")
(assert-equal test
&(the (Maybe Char) (Maybe.Nothing))
&(last &[])
"last works as expected on empty array")
(assert-equal test
&[3 2 1]
&(reverse [1 2 3])
@ -227,12 +243,12 @@
(find &(fn [x] (= 0 @x)) &(range 1 10 1))
"find works as expected II")
(assert-equal test
-1
(find-index &(fn [i] (Int.even? @i)) &[1 3 5])
&(Maybe.Nothing)
&(find-index &(fn [i] (Int.even? @i)) &[1 3 5])
"find-index works I")
(assert-equal test
1
(find-index &(fn [i] (Int.even? @i)) &[1 8 5])
&(Maybe.Just 1)
&(find-index &(fn [i] (Int.even? @i)) &[1 8 5])
"find-index works II")
(assert-equal test
2

View File

@ -4,34 +4,53 @@
(deftest test
(assert-true test
(nothing? &(the (Maybe Int) (Nothing)))
"nothing? works on Nothing")
"nothing? works on Nothing"
)
(assert-false test
(nothing? &(Just 1))
"nothing? works on Just")
"nothing? works on Just"
)
(assert-true test
(just? &(Just 1))
"just? works on Just")
"just? works on Just"
)
(assert-false test
(just? &(the (Maybe Int) (Nothing)))
"just? works on Nothing")
"just? works on Nothing"
)
(assert-equal test
1
(from (Just 1) 0)
"from works on Just")
"from works on Just"
)
(assert-equal test
0
(from (the (Maybe Int) (Nothing)) 0)
"from works on Nothing")
"from works on Nothing"
)
(assert-equal test
1
(unsafe-from (Just 1))
"unsafe-from works on Just")
"unsafe-from works on Just"
)
(assert-equal test
2
(from (apply (Just 1) Int.inc) 0)
"apply works on Just")
"apply works on Just"
)
(assert-equal test
0
(from (apply (the (Maybe Int) (Nothing)) Int.inc) 0)
"apply works on Nothing")
"apply works on Nothing"
)
(assert-equal test
&(Result.Success 1)
&(to-result (Just 1) "error")
"to-result works on Just"
)
(assert-equal test
&(the (Result Int (Ref String)) (Result.Error "error"))
&(to-result (Nothing) "error")
"to-result works on Nothing"
)
)

View File

@ -211,12 +211,12 @@
(defn array-first []
(let [xs [@"a" @"b" @"c"]
result (Array.first &xs)]
result (Array.unsafe-first &xs)]
(assert (= @"a" result))))
(defn array-last []
(let [xs [@"a" @"b" @"c"]
result (Array.last &xs)]
result (Array.unsafe-last &xs)]
(assert (= @"c" result))))
(defn array-eq-1 []

View File

@ -3,14 +3,30 @@
(use-all Test Result)
(deftest test
(assert-true test
(success? &(the (Result Int (Ref String)) (Success 1)))
"success? works with Success"
)
(assert-false test
(success? &(the (Result Int (Ref String)) (Error "error")))
"success? works with Error"
)
(assert-true test
(error? &(the (Result Int (Ref String)) (Error "error")))
"error? works with Error"
)
(assert-false test
(error? &(the (Result Int (Ref String)) (Success 1)))
"error? works with Success"
)
(assert-equal test
1
(apply (Success 0) Int.inc Int.dec)
&(Success 1)
&(apply (Success 0) Int.inc Int.dec)
"apply works with Success"
)
(assert-equal test
-1
(apply (Error 0) Int.inc Int.dec)
&(Error -1)
&(apply (Error 0) Int.inc Int.dec)
"apply works with Error"
)
(assert-true test
@ -19,7 +35,7 @@
)
(assert-equal test
&(Success 2)
&(map (the (Result Int String) (Success 1)) Int.inc)
&(map (the (Result Int (Ref String)) (Success 1)) Int.inc)
"map works with Success"
)
(assert-true test
@ -28,83 +44,81 @@
)
(assert-equal test
&(Success 2)
&(and-then (the (Result Int String) (Success 1))
&(and-then (the (Result Int (Ref String)) (Success 1))
(fn [x] (Success (Int.inc x))))
"and-then works with Success"
)
(assert-equal test
2
(unwrap-or-zero (the (Result Int (Ref String)) (Success 2)))
"unwrap-or-zero works with Success"
)
(assert-equal test
0
(unwrap-or-zero (Error "error"))
"unwrap-or-zero works with Error"
)
(assert-equal test
&(Error 5)
&(or-else (the (Result Int (Ref String)) (Error "error"))
(fn [x] (Error (String.length x))))
"or-else works with Error"
)
(assert-equal test
&(Success 1)
&(or-else (Success 1) (fn [x] (Error (String.length x))))
"or-else works with Success"
)
(assert-equal test
5
(unwrap-or-else (the (Result Int (Ref String)) (Error "error"))
String.length)
"unwrap-or-else works with Error"
)
(assert-equal test
1
(unwrap-or-else (Success 1) String.length)
"unwrap-or-else works with Success"
)
(assert-equal test
1
(unsafe-from-success (the (Result Int (Ref String)) (Success 1)))
"unsafe-from-success works with Success"
)
(assert-equal test
1
(from-success (the (Result Int (Ref String)) (Success 1)) 0)
"from-success works with Success"
)
(assert-equal test
0
(from-success (Error "error") 0)
"from-success works with Error"
)
(assert-equal test
"error"
&(unsafe-from-error (the (Result Int String) (Error @"error")))
"unsafe-from-Error works with Error"
)
(assert-equal test
"error"
&(from-error (the (Result Int String) (Error @"error"))
@"success")
"from-error works with Error"
)
(assert-equal test
"success"
&(from-error (Success 1) @"success")
"from-error works with Success"
)
(assert-equal test
&(Maybe.Just 1)
&(to-maybe (the (Result Int (Ref String)) (Success 1)))
"to-maybe works with Success"
)
(assert-equal test
&(Maybe.Nothing)
&(to-maybe (the (Result Int (Ref String)) (Error "error")))
"to-maybe works with Error"
)
)
; (defn and-then [a f]
; (match a
; (Success x) (f x)
; (Error x) (Error x)))
;
; (defn unwrap-or-zero [a]
; (match a
; (Success x) x
; (Error _) (zero)))
;
; (defn and [a b]
; (match a
; (Success _) b
; (Error x) (Error x)))
;
; (defn or [a b]
; (match a
; (Success x) (Success x)
; (Error _) b))
;
; (defn or-else [a f]
; (match a
; (Success x) (Success x)
; (Error x) (f x)))
;
; (defn unwrap-or-else [a f]
; (match a
; (Success x) x
; (Error x) (f x)))
;
; (defn unsafe-from-success [a]
; (match a
; (Success x) x))
;
; (defn from-success [a dflt]
; (match a
; (Error _) dflt
; (Success x) x))
;
; (defn unsafe-from-error [a]
; (match a
; (Error x) x))
;
; (defn from-error [a dflt]
; (match a
; (Success _) dflt
; (Error x) x))
;
; (defn to-maybe [a]
; (match a
; (Success x) (Maybe.Just x)
; (Error _) (Maybe.Nothing)))
;
; (defn success? [a]
; (match @a
; (Error _) false
; (Success _) true))
;
; (defn error? [a]
; (match @a
; (Error _) true
; (Success _) false))
;
; (defn = [a b]
; (match @a
; (Success x)
; (match @b
; (Error _) false
; (Success y) (= x y))
; (Error x)
; (match @b
; (Success _) false
; (Error y) (= x y))))
;)