diff options
author | Louis Pilfold <louis@lpil.uk> | 2020-05-22 19:32:05 +0100 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2020-05-26 19:19:29 +0100 |
commit | cd2e4bf6176f2a8a0cd0ce0e1f3c463a9182c514 (patch) | |
tree | 9d1bc253869438b1606581d585b4ca7f7b05c7e6 /src | |
parent | 3fefc3fc5efccbedacbf16a52b9531efa0d9ab30 (diff) | |
download | gleam_stdlib-cd2e4bf6176f2a8a0cd0ce0e1f3c463a9182c514.tar.gz gleam_stdlib-cd2e4bf6176f2a8a0cd0ce0e1f3c463a9182c514.zip |
Queue data type
Diffstat (limited to 'src')
-rw-r--r-- | src/gleam/queue.gleam | 105 | ||||
-rw-r--r-- | src/gleam/should.gleam | 12 | ||||
-rw-r--r-- | src/gleam_stdlib.erl | 5 |
3 files changed, 114 insertions, 8 deletions
diff --git a/src/gleam/queue.gleam b/src/gleam/queue.gleam new file mode 100644 index 0000000..b3278b1 --- /dev/null +++ b/src/gleam/queue.gleam @@ -0,0 +1,105 @@ +import gleam/list + +// TODO: document +pub opaque type Queue(element) { + Queue(in: List(element), out: List(element)) +} + +// TODO: document +pub fn new() -> Queue(a) { + Queue(in: [], out: []) +} + +// TODO: document +pub fn from_list(list: List(a)) -> Queue(a) { + Queue(in: list, out: []) +} + +// TODO: document +pub fn to_list(queue: Queue(a)) -> List(a) { + queue.in + |> list.append(list.reverse(queue.out)) +} + +// TODO: document +pub fn is_empty(queue: Queue(a)) -> Bool { + queue.in == [] && queue.out == [] +} + +// TODO: document +pub fn length(queue: Queue(a)) -> Int { + list.length(queue.in) + list.length(queue.out) +} + +// TODO: document +pub fn push_back(onto queue: Queue(a), this item: a) -> Queue(a) { + Queue(in: [item, ..queue.in], out: queue.out) +} + +// TODO: document +pub fn push_front(onto queue: Queue(a), this item: a) -> Queue(a) { + Queue(in: queue.in, out: [item, ..queue.out]) +} + +// TODO: document +pub fn pop_back(from queue: Queue(a)) -> Result(tuple(a, Queue(a)), Nil) { + case queue { + Queue(in: [], out: []) -> Error(Nil) + Queue(in: in, out: []) -> pop_back(Queue(in: [], out: list.reverse(in))) + Queue(in: in, out: [first, ..rest]) -> { + let queue = Queue(in: in, out: rest) + Ok(tuple(first, queue)) + } + } +} + +// TODO: document +pub fn pop_front(from queue: Queue(a)) -> Result(tuple(a, Queue(a)), Nil) { + case queue { + Queue(in: [], out: []) -> Error(Nil) + Queue(in: [], out: out) -> pop_front(Queue(in: list.reverse(out), out: [])) + Queue(in: [first, ..rest], out: out) -> { + let queue = Queue(in: rest, out: out) + Ok(tuple(first, queue)) + } + } +} + +// TODO: document +// O(1) +pub fn reverse(queue: Queue(a)) -> Queue(a) { + Queue(in: queue.out, out: queue.in) +} + +fn check_equal( + xs: List(t), + x_tail: List(t), + ys: List(t), + y_tail: List(t), + eq: fn(t, t) -> Bool, +) -> Bool { + case xs, x_tail, ys, y_tail { + [], [], [], [] -> True + [x, ..xs], _, [y, ..ys], _ -> case eq(x, y) { + False -> False + True -> check_equal(xs, x_tail, ys, y_tail, eq) + } + [], [_, ..], _, _ -> check_equal(list.reverse(x_tail), [], ys, y_tail, eq) + _, _, [], [_, ..] -> check_equal(xs, x_tail, list.reverse(y_tail), [], eq) + _, _, _, _ -> False + } +} + +// TODO: document +pub fn is_logically_equal( + a: Queue(t), + to b: Queue(t), + checking element_is_equal: fn(t, t) -> Bool, +) -> Bool { + check_equal(a.out, a.in, b.out, b.in, element_is_equal) +} + +// TODO: document +pub fn is_equal(a: Queue(t), to b: Queue(t)) -> Bool { + check_equal(a.out, a.in, b.out, b.in, fn(a, b) { a == b }) +} diff --git a/src/gleam/should.gleam b/src/gleam/should.gleam index de07f10..9f88314 100644 --- a/src/gleam/should.gleam +++ b/src/gleam/should.gleam @@ -14,11 +14,15 @@ pub external fn equal(a, a) -> Expectation = pub external fn not_equal(a, a) -> Expectation = "gleam_stdlib" "should_not_equal" -pub external fn be_true(Bool) -> Expectation = - "gleam_stdlib" "should_be_true" +pub fn be_true(actual: Bool) -> Expectation { + actual + |> equal(True) +} -pub external fn be_false(Bool) -> Expectation = - "gleam_stdlib" "should_be_false" +pub fn be_false(actual: Bool) -> Expectation { + actual + |> equal(False) +} pub external fn be_ok(Result(a, b)) -> Expectation = "gleam_stdlib" "should_be_ok" diff --git a/src/gleam_stdlib.erl b/src/gleam_stdlib.erl index fc5499c..1b33126 100644 --- a/src/gleam_stdlib.erl +++ b/src/gleam_stdlib.erl @@ -1,8 +1,7 @@ -module(gleam_stdlib). -include_lib("eunit/include/eunit.hrl"). --export([should_equal/2, should_not_equal/2, should_be_true/1, - should_be_false/1, should_be_ok/1, should_be_error/1, +-export([should_equal/2, should_not_equal/2, should_be_ok/1, should_be_error/1, atom_from_string/1, atom_create_from_string/1, atom_to_string/1, map_get/2, iodata_append/2, iodata_prepend/2, identity/1, decode_int/1, decode_string/1, decode_bool/1, decode_float/1, @@ -13,8 +12,6 @@ should_equal(Actual, Expected) -> ?assertEqual(Expected, Actual). should_not_equal(Actual, Expected) -> ?assertNotEqual(Expected, Actual). -should_be_true(A) -> ?assert(A). -should_be_false(A) -> ?assertNot(A). should_be_ok(A) -> ?assertMatch({ok, _}, A). should_be_error(A) -> ?assertMatch({error, _}, A). |