Number Lists
Generalizing the definition of pairs, we can describe the type of number lists as follows: "A list is either the empty list or a set of one element and another list", this type is not composed of a head
and a tail
.
type List (t) {
nil
cons (head: t) (tail: List t)
}
As we are dealing with only one type, it is interesting to rewrite the list type for a defined one, the chosen one was Nat
:
type NatList {
nil
cons (head: Nat) (tail: NatList)
}
or
type NatList {
List Nat
}
We can see that in both notations, there is a head
and a tail
, with the
head
receiving an element of type Nat
and the tail
receiving a list of type Nat
.
For example, a list of three natural numbers 1n, 2n, and 3n would be written as follows:
[1n, 2n, 3n]
However, the Kind reads it differently:
[1n, [2n, 3n]]
where 1n
is the head and [2n, 3n]
is the tail. Likewise, looking at a
list of 4 elements [1n, 2n, 3n, 4n]
, we now see it as follows:
[1n, [2n, [3n, 4n]]]
The list has the head
1n
and the tail
[2n, [3n, 4n]]
, which, in turn, has the
head
2n
and the tail
[3n, 4n]
which also has its head
3n
and its tail
4n
.
It may seem scary, but it's a friendly monster:
[fonte da imagem: http://learnyouahaskell.com/starting-out]
Repeat
The function repeat
takes a number n
and a value, returning a list of size n
where all elements are the declared value.
// Exemplo: (Repeat 3 Bool.true) -> [True, True, True]
Repeat (x: Nat) (count: Nat) : List Nat
Repeat x Nat.zero = []
Repeat x (Nat.succ count) = List.cons Nat x (Repeat count x)
Length
The function length
calculates the size of the list.
// Exemplo: (Length [1,2,3]) -> 3
Length (xs: List Nat) : Nat
Length List.nil = 0n
Length (List.cons head tail) = (Nat.succ (Length tail))
Concat
The function concat
concatenates (appends) two lists.
Concat (xs: List Nat) (ys: List Nat) : List Nat
Concat (List.nil) ys = ys
Concat (List.cons head tail) ys = List.cons Nat head (Concat tail ys)
Head and Tail
The head function returns the first element (the "head") of the list, while tail returns everything except the first element (the "tail"). Of course, an empty list has no first element, so we must handle this case with a Maybe
type, receiving a Maybe.none
if the list is empty or a Maybe.some
if it has a value.
// Exemplo: (Head 0n [1n,2n,3n]) -> 1n
Head (default: Nat) (xs: List Nat) : Nat
Head default (List.nil) = default
Head default (List.cons head tail) = head
// Exemplo: (Tail Nat [1,2,3]) -> [2,3]
Tail (xs: List Nat) : List Nat
Tail (List.nil) = []
Tail (List.cons head tail) = tail
Test_head1 : Equal Nat (Head 0n [1n,2n,3n]) 1n
Test_head1 = Equal.refl
Test_head2 : Equal Nat (Head 0n List.nil) 0n
Test_head2 = Equal.refl
Test_head3 : Equal (List Nat) (Tail [1n, 2n, 3n]) [2n, 3n]
Test_head3 = Equal.refl
Exercises
List_funs
Complete the definitions of Nonzeros, Oddmembers, and Countoddmembers below. Take a look at the tests to understand what these functions should do.
Nonzeros (xs: List Nat) : List Nat
Nonzeros xs = ?
Test_nonzeros : Equal (List Nat) (Nonzeros [0n,1n,0n,2n,3n,0n,0n]) [1n,2n,3n]
Test_nonzeros = ?
Oddmembers (xs: List Nat) : List Nat
Oddmembers xs = ?
Test_oddmembers : Equal (List Nat) (Oddmembers [0n,1n,0n,2n,3n,0n,0n]) [1n,3n]
Test_oddmembers = ?
CountOddMembers (xs: List Nat) : Nat
CountOddMembers xs = ?
Test_countoddmembers1 : Equal Nat (CountOddMembers [1n,0n,3n,1n,4n,5n]) 4n
Test_countoddmembers1 = ?
Alternate
Complete the definition of alternate, which compacts
two lists into one, alternating between elements taken from the first list and elements from the second. See the tests below for more specific examples.
Alternate (xs: List Nat) (ys: List Nat) : List Nat
Alternate xs ys = ?
Test_alternate1 : Equal (List Nat) (Alternate [1n,2n,3n] [4n,5n,6n]) [1n,4n,2n,5n,3n,6n]
Test_alternate1 = ?
Test_alternate2 : Equal (List Nat) (Alternate [1n] [4n,5n,6n]) [1n,4n,5n,6n]
Test_alternate2 = ?
Test_alternate3 : Equal (List Nat) (Alternate [1n,2n,3n] [4n]) [1n,4n,2n,3n]
Test_alternate3 = ?
Test_alternate4 : Equal (List Nat) (Alternate [] [20n,30n]) [20n,30n]
Test_alternate4 = ?
Functions
Complete the following definitions for the count, sum, add, and member functions of natural number lists.
Count (v: Nat) (xs: List Nat) : Nat
Count v xs = ?
Test_count1 : Equal Nat (Count 1n [1n,2n,3n,1n,4n,1n]) 3n
Test_count1 = ?
Test_count2 : Equal Nat (Count 6n [1n,2n,3n,1n,4n,1n]) 0n
Test_count2 = ?
Sum (xs: List Nat) (ys: List Nat) : List Nat
Sum xs ys = ?
Test_sum1 : Equal Nat (Count 1n (Sum [1n,2n,3n] [1n,4n,1n])) 3n
Test_sum1 = ?
Add (n: Nat) (xs: List Nat) : List Nat
Add n xs = ?
Test_add1 : Equal Nat (Count 1n (Add 1n [1n,4n,1n])) 3n
Test_add1 = ?
Test_add2 : Equal Nat (Count 5n (Add 1n [1n,4n,1n])) 0n
Test_add2 = ?
Member (v: Nat) (xs: List Nat) : Bool
Member v xs = ?
Test_member1 : Equal Bool (Member 1n [1n,4n,1n]) Bool.true
Test_member1 = ?
Test_member2 : Equal Bool (Member 2n [1n,4n,1n]) Bool.false
Test_member2 = ?
More_functions
Here are some more functions of List Nat
for you to practice with. When remove_one is applied to a list without the number to be removed, it should return the same unchanged list.
Remove_one (v: Nat) (xs: List Nat) : List Nat
Remove_one v xs = ?
Test_remove_one1 : Equal Nat (Count 5n (Remove_one 5n [2n,1n,5n,4n,1n])) 0n
Test_remove_one1 = ?
Test_remove_one2 : Equal Nat (Count 5n (Remove_one 5n [2n,1n,4n,1n])) 0n
Test_remove_one2 = ?
Test_remove_one3 : Equal Nat (Count 4n (Remove_one 5n [2n,1n,5n,4n,1n,4n])) 2n
Test_remove_one3 = ?
Test_remove_one4 : Equal Nat (Count 5n (Remove_one 5n [2n,1n,5n,4n,5n,1n,4n])) 1n
Test_remove_one4 = ?
Remove_all (v: Nat) (xs: List Nat) : List Nat
Remove_all v xs = ?
Test_remove_all1 : Equal Nat (Count 5n (Remove_all 5n [2n,1n,5n,4n,1n])) 0n
Test_remove_all1 = ?
Test_remove_all2 : Equal Nat (Count 5n (Remove_all 5n [2n,1n,4n,1n])) 0n
Test_remove_all2 = ?
Test_remove_all3 : Equal Nat (Count 4n (Remove_all 5n [2n,1n,5n,4n,1n,4n])) 2n
Test_remove_all3 = ?
Test_remove_all4 : Equal Nat (Count 5n (Remove_all 5n [2n,1n,5n,4n,5n,1n,4n,5n,1n,4n])) 0n
Test_remove_all4 = ?
Subset (xs: List Nat) (ys: List Nat) : Bool
Subset xs ys = ?
Test_subset1 : Equal Bool (Subset [1n,2n] [2n,1n,4n,1n]) Bool.true
Test_subset1 = ?
Test_subset2 : Equal Bool (Subset [1n,2n,2n] [2n,1n,4n,1n]) Bool.false
Test_subset2 = ?
Theorem
Write down an interesting theorem involving the count and add functions and prove it. Note that, as this problem is somewhat open-ended, you may come up with a theorem that is true but whose proof requires techniques you have not yet learned. Feel free to ask for help if you get stuck!
Theorem : ?