Bend/examples/list.bend

202 lines
4.4 KiB
Plaintext
Raw Permalink Normal View History

2024-05-23 00:15:39 +03:00
##############################
# Author: Ematth, 2024
##############################
### Singly-Linked List Type Definition: ###
# The List type is builtin, so we don't need to declare it.
# But this is how it's defined in the builtins file.
2024-05-23 00:15:39 +03:00
# type List:
# Nil
# Cons { head, ~tail }
2024-05-23 00:15:39 +03:00
###########################################
# List clear:
# List l -> list l
2024-05-29 22:21:55 +03:00
# clears all elements from list l. This is equivalent to initializing an empty list.
2024-06-21 21:16:10 +03:00
clear = @l []
2024-05-23 00:15:39 +03:00
# List concat:
# List l -> List l
# combines two lists (l1, l2) from left to right.
2024-06-21 21:16:10 +03:00
concat = @l1 @l2
2024-05-23 00:15:39 +03:00
match l1 {
2024-06-21 21:16:10 +03:00
List/Cons: (List/Cons l1.head (concat l1.tail l2))
2024-05-23 00:15:39 +03:00
List/Nil: l2
}
# List add_front:
# List l -> List l
# adds a non-List element e to the front of list l.
2024-06-21 21:16:10 +03:00
add_front = @l @e
2024-05-23 00:15:39 +03:00
match l {
List/Cons: (List/Cons e l)
List/Nil: (List/Cons e List/Nil)
}
# List append (add_back):
# List l -> List l
# adds a non-list element e to the back of list l.
2024-06-21 21:16:10 +03:00
append = @l @e
(concat l (List/Cons e List/Nil))
2024-05-23 00:15:39 +03:00
2024-05-24 23:28:38 +03:00
# list sum:
# List l -> uint
2024-05-29 22:21:55 +03:00
# returns the sum of all items in the list.
2024-06-21 21:16:10 +03:00
sum = @l
2024-05-24 23:28:38 +03:00
match l {
2024-06-21 21:16:10 +03:00
List/Cons: (+ l.head (sum l.tail))
2024-05-24 23:28:38 +03:00
List/Nil: 0
}
2024-05-23 00:15:39 +03:00
# List reverse:
# List l -> List l
# reverses the order of elements in list l.
2024-06-21 21:16:10 +03:00
reverse.aux = @acc @l
2024-05-23 00:15:39 +03:00
match l {
List/Nil: acc
2024-06-21 21:16:10 +03:00
List/Cons: (reverse.aux (List/Cons l.head acc) l.tail)
2024-05-23 00:15:39 +03:00
}
2024-06-21 21:16:10 +03:00
reverse = @l
(reverse.aux [] l)
2024-05-23 00:15:39 +03:00
# List length:
# List l -> uint
# returns the number of elements in list l.
2024-06-21 21:16:10 +03:00
len = @l
2024-05-23 00:15:39 +03:00
match l {
2024-05-23 01:00:52 +03:00
List/Nil: 0
2024-06-21 21:16:10 +03:00
List/Cons: (+ 1 (len l.tail))
2024-05-23 00:15:39 +03:00
}
# List count:
2024-05-23 01:00:52 +03:00
# List l -> uint -> uint
2024-05-29 22:21:55 +03:00
# returns the number of instances of Some s in list l.
2024-06-21 21:16:10 +03:00
count.aux = @acc @l @s
2024-05-23 00:15:39 +03:00
match l {
2024-05-24 23:28:38 +03:00
List/Nil: acc
2024-05-23 00:15:39 +03:00
List/Cons: use acc = switch (== l.head s) {
0: acc;
_: (+ acc 1);
}
2024-06-21 21:16:10 +03:00
(count.aux acc l.tail s)
2024-05-23 00:15:39 +03:00
}
2024-06-21 21:16:10 +03:00
count = @l @s
(count.aux 0 l s)
2024-05-23 00:15:39 +03:00
# List index:
# List l -> Some s
# returns the value of a specific list index i, or * if the index doesn't exist.
2024-06-21 21:16:10 +03:00
index = @l @i
2024-05-23 00:15:39 +03:00
match l {
List/Cons:
switch i {
0: l.head
2024-06-21 21:16:10 +03:00
_: (index l.tail (i-1))
2024-05-23 00:15:39 +03:00
}
List/Nil: *
}
2024-05-29 22:21:55 +03:00
# List head:
# List l -> Some s
# returns the first item in the list, or [] if the list is empty.
2024-06-21 21:16:10 +03:00
head = @l
2024-05-29 22:21:55 +03:00
match l {
List/Cons: l.head
List/Nil: []
}
2024-08-08 19:37:22 +03:00
# List tail:
# List l -> List
# returns the list except for the first item in it, or [] if the list is empty.
def tail(l):
match l:
case List/Cons:
return l.tail
case List/Nil:
return []
# List equals:
# List xs, List ys, function cmp -> 1|0
# Compares the elements in two lists and returns 1 if they're equal, and 0 otherwise.
# The function cmp compares two values and returns 1 if they're equal, and 0 otherwise.
equals xs ys cmp = match xs {
List/Cons: match ys {
List/Cons: if (cmp xs.head ys.head) {
(equals xs.tail ys.tail cmp)
} else {
0
}
List/Nil: 0
}
List/Nil: match ys {
List/Cons: 0
List/Nil: 1
}
}
2024-05-23 00:15:39 +03:00
# List pop_front:
2024-05-29 22:21:55 +03:00
# List l -> List l
# removes and discards the first item of list l.
# The new list is returned, or [] if the list is empty.
2024-06-21 21:16:10 +03:00
pop_front = @l
2024-05-23 00:15:39 +03:00
match l {
2024-05-29 22:21:55 +03:00
List/Cons: l.tail
2024-05-23 00:15:39 +03:00
List/Nil: []
}
# List pop_back:
# List l -> List l
2024-05-29 22:21:55 +03:00
# removes and discards the the last item of list l.
2024-06-21 21:16:10 +03:00
pop_back (List/Nil) = List/Nil
pop_back (List/Cons x List/Nil) = List/Nil
pop_back (List/Cons head tail) = (List/Cons head (pop_back tail))
2024-05-23 00:15:39 +03:00
# List remove:
# List l -> Some s -> List l
# removes the first occurrence of element e from list l.
2024-06-21 21:16:10 +03:00
remove = @l @s
2024-05-23 00:15:39 +03:00
match l {
List/Cons:
switch (== l.head s) {
2024-06-21 21:16:10 +03:00
0: (List/Cons l.head (remove l.tail s))
2024-05-23 00:15:39 +03:00
_: l.tail
}
List/Nil: List/Nil
}
# List split:
# list l -> uint i -> (List l, list l)
# splits list l into two lists (l1, l2) at index i.
# the second list takes the element at index i during the split.
2024-06-21 21:16:10 +03:00
split = @l @i (split.aux [] l i)
split.aux = @acc @l @i
2024-05-23 00:15:39 +03:00
match l {
List/Cons:
switch i {
0: (acc, l)
2024-06-21 21:16:10 +03:00
_: (split.aux (append acc l.head) l.tail i-1)
2024-05-23 00:15:39 +03:00
}
List/Nil: *
}
2024-06-21 21:16:10 +03:00
2024-05-23 00:15:39 +03:00
#################################
2024-05-29 22:21:55 +03:00
def main:
2024-06-21 21:16:10 +03:00
return head([5, 4, 3, 2, 1])
# return sum([1, 2, 3])
# return split([1, 2, 3, 4, 5, 6, 7], 3)
# return remove([1, 2, 1, 3], 1)
# return pop_back([1, 2, 3, 4])
# return pop_front([1, 2, 3])
# return index([5, 3, 6, 8, 2], 0)
# return clear([0, 2, 3])
# return count([1, 2, 3, 3, 3, 4, 4, 5, 3, 1000], 4)
# return len([1, 2, 3, 4, 4, 4])
# return reverse([1, 2, 3, 4, 5])
# return append([1, 2], 3)
# return add_front([2, 3], 1)
# return concat([1, 2], [3, 4])