FEATURE: Add a slice module to our lists library.

This commit is contained in:
Jeremy Wall 2019-02-27 19:33:14 -06:00
parent b334482822
commit ea3f2eae5f
3 changed files with 71 additions and 0 deletions

View File

@ -63,6 +63,19 @@ let hd = l.head([0,1,2,3]);
tail == [0];
```
## slice
The slice module returns a slice of the input list. The slice module takes three
parameters.
* `start` which is optional and defaults to 0
* `end` which is optional and defaults the length of the list
* `list` which is required and must be a list.
```
list.slice{start=0, end=2, list=[0,1,2,3]} == [0,1,2];
```
## enumerate
The enumerate module enumerates the elements of a list. It has three parameters.

View File

@ -70,6 +70,39 @@ let enumerate = module{
(mod.list)).list;
};
// slice returns a slice of a list starting at index start up to and
// including index end, inclusive.
let slice = module {
start = 0,
end = NULL,
list = NULL,
} => (result) {
let list = import "std/lists.ucg";
let list_len = list.len(mod.list);
let end = select mod.end is "null", mod.end, {
true = list_len,
};
// ensure some invariants
(mod.start >= 0) || fail "Slice must be positive";
(mod.start <= list_len) || fail "Slice start cannot be larger than the list len of @" % (list_len);
(end <= list_len) || fail "Slice end cannot be larger than list len of @" % (list_len);
let reducer = func(acc, item) => acc{
count = acc.count + 1,
list = select (acc.count >= mod.start) && (acc.count <= end), acc.list, {
true = acc.list + [item],
},
};
let result = reduce(
reducer,
{count=mod.start, list=[]},
mod.list).list;
};
// zips two lists together.
//
// zip{list1=[0,2,4],list2=[1,3,5]}.result == [[0, 1], [2, 3], [4, 5]]

View File

@ -52,4 +52,29 @@ assert asserts.equal{
assert asserts.equal{
left=list.head([0,1,2,3,4]),
right=[0],
};
assert asserts.equal{
left=list.slice{end=2, list=[0,1,2,3]},
right=[0,1,2],
};
assert asserts.equal{
left=list.slice{list=[0,1,2,3]},
right=[0,1,2,3],
};
assert asserts.equal{
left=list.slice{end=0, list=[0,1,2,3]},
right=[0],
};
assert asserts.equal{
left=list.slice{list=[]},
right=[],
};
assert asserts.equal{
left=list.slice{list=[0]},
right=[0],
};