-
Notifications
You must be signed in to change notification settings - Fork 7
/
List.ele
79 lines (62 loc) · 2.5 KB
/
List.ele
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#[[ List constructor.
# list(...):List
# Create a literal List from the parameters.
# Elements must be homogeneous.
#
# Example:
# list(1, 2, 3)
#]]
intrinsic function list:List
#[[ Represent a finite set of elements ]]
intrinsic struct List(at:Indexer, count:Num)
{
#[[ Summarise a List
#
# Invoke accumulator(total, element) with each element of the list,
# starting with initial as the total and returning a new total each iteration.
# For example:
# fold(list(1, 2, 3), 0, Num.add)
# evaluates to:
# Num.add(Num.add(Num.add(0, 1), 2), 3)
#]]
intrinsic function fold(list:List, initial, accumulator:Binary)
#[[ Apply a mapper to each element of the list ]]
map(a:List, mapper:Unary):List = List(_(idx:Num) = mapper(a.at(idx)), a.count)
zip(a:List, b:List, zipper:Binary):List = List(_(idx:Num) = zipper(a.at(idx), b.at(idx)), a.count)
repeat(value, count:Num):List = List(_(_:Num) = value, count)
range(start:Num, count:Num):List = List(_(idx:Num) = idx.add(start), count)
concatenate(a:List, b:List):List
{
indexer(idx:Num) = Bool.if(idx.lt(a.count), a.at(idx), b.at(idx.sub(a.count)))
count = a.count.add(b.count)
return = List(indexer, count)
}
take(a:List, amount:Num):List = List(a.at, amount)
skip(a:List, amount:Num):List
{
count = a.count.sub(amount)
indexer(idx:Num) = a.at(idx.add(amount))
return = List(indexer, count)
}
slice(a:List, start:Num, count:Num):List = List(_(idx) = a.at(idx.add(start)), count)
filter(a:List, predicate:Predicate):List
{
count = countWhere(a, predicate)
index(idx:Num) = idx.add(a.slice(0, idx).countWhere(_(item) = predicate(item).negate))
return = List(index, count)
}
cycle(a:List):Stream = Stream(_(idx:Num) = a.at(idx.mod(a.count)))
countWhere(a:List, predicate:Predicate):Num = a.fold(0, _(current, next) = if(predicate(next), Num.add(current, 1), current))
reverse(a:List):List = List(_(idx:Num) = a.at(a.count.sub(idx).sub(1)), a.count)
findLast(a:List, predicate:Predicate, default) = a.fold(default, _(current, next) = predicate(next).if(next, current))
findFirst(a:List, predicate:Predicate, default) = a.reverse.findLast(predicate, default)
first(a:List) = a.at(0)
last(a:List) = a.at(a.count.sub(1))
enumerate(this:List):List
{
return = List(
_(i:Num) = {idx=i, val=this.at(i)},
this.count
)
}
}