{-# OPTIONS --cubical-compatible #-}
module Padova2025.ProgrammingBasics.Lists where
Lists
In the Agda community, lists are usually written like
a β· b β· c β· [], or more precisely
a β· (b β· (c β· [])). The symbol [] denotes the
empty list. The operator _β·_ is used for appending
(βconsingβ) a single element in front of an already existing tail of
elements. The code to implement this syntax is the following.
infixr 5 _β·_ data List (A : Set) : Set where -- enter `β·` by `\::` [] : List A _β·_ : A β List A β List A
The variable A appearing in this datatype definition is
a parameter. In effect, for each type A, a new
type List A is introduced. If Agda didnβt support
parameters, we would be forced to repeat ourselves, for instance with
tedious code as the following.
data ListOfBools : Set where
[] : ListOfBools
_β·_ : Bool β ListOfBools β ListOfBools
data ListOfNats : Set where
[] : ListOfNats
_β·_ : β β ListOfNats β ListOfNats
Exercise: Summing lists
open import Padova2025.ProgrammingBasics.Naturals.Base open import Padova2025.ProgrammingBasics.Naturals.Arithmetic
Define a function which sums the elements of a given list of natural numbers.
sum : List β β β
sum = {!!}
Exercise: Length of lists
Define a function which computes the length of a given list.
length : {A : Set} β List A β β
length = {!!}
The parameter A is here put in curly brackets so that
when calling length, it does not need to be explicitly
mentioned: From the explicit argument, a certain list, Agda is able to
infer the type of its elements.
Exercise: Replication
Define a function replicate which reads a number
n and an element x as input and outputs a list
containing n copies of x.
replicate : {A : Set} β β β A β List A
replicate = {!!}
Exercise: Concatenation
Define a binary operator which concatenates two lists. For instance,
(a β· b β· []) ++ (c β· d β· []) should reduce to
a β· b β· c β· d β· [].
infixr 5 _++_
_++_ : {A : Set} β List A β List A β List A
_++_ = {!!}
Exercise: Dropping initial elements
For instance, drop one (a β· b β· c β· []) should evaluate
to b β· c β· [].
drop : {A : Set} (k : β) β List A β List A
drop = {!!}
Exercise: Mapping over lists
Define the map function, which should apply the supplied
function f to each element in the input list.
For instance, map f (x β· y β· z β· []) should reduce to
f x β· f y β· f z β· [].
map : {A B : Set} β (A β B) β List A β List B
map = {!!}
Exercise: Snocking
For instance, (a β· b β· c β· []) β·Κ³ z should reduce to
a β· b β· c β· z β· [].
_β·Κ³_ : {A : Set} β List A β A β List A
_β·Κ³_ = {!!}
Exercise: Reversal
Write a function which reverses the elements of a list. For instance,
reverse (a β· b β· c β· []) should reduce to
c β· b β· a β· [].
reverse : {A : Set} β List A β List A
reverse = {!!}
Exercise: Countdown
Implement a function downFrom which reads a number
n as input and outputs the length-n list of
numbers from n (exclusively) to 0
(inclusively). For instance, downFrom three should reduce
to two β· one β· zero β· [].
downFrom : β β List β
downFrom = {!!}
Similarly, implement a function upTo : β β List β such
that for instance upTo three reduces to
zero β· one β· two β· [].
upTo : β β List β
upTo = {!!}
Exercise: A higher-kinded function
The Agda expressions List β, List Bool and
so on denote certain types, i.e. elements of Set. Is the
bare expression List, without any argument, also
meaningful? What is its type?
List' : {!!}
List' = List
In Haskellβs two-level type system with types governing values and
βkindsβ governing types, List would be called a βtype
constructorβ of kind * β *.