Tutorial
Tutorials.Thursday-Complete
Tutorials.Thursday-Complete{-# OPTIONS --guardedness #-}
import Tutorials.Monday-Complete as Mon
import Tutorials.Tuesday-Complete as Tue
import Tutorials.Wednesday-Complete as Wed
open Mon using (⊤; tt; ℕ; zero; suc)
open Mon.Simple using (_⊎_; inl; inr)
open Tue.Product using (Σ; _,_; fst; snd; _×_)
module Tutorials.Thursday-Complete where
variable
A B C S : Set
module WithAbstraction where
open Mon using (Bool; true; false; Pred; _≡_; refl; _+_; subst; +-comm)
open Mon.List using (List; []; _∷_)
filter : (A → Bool) → List A → List A
filter f [] = []
filter f (x ∷ xs) with f x
filter f (x ∷ xs) | true = x ∷ filter f xs
filter f (x ∷ xs) | false = filter f xs
filter′ : (A → Bool) → List A → List A
filter′ f [] = []
filter′ f (x ∷ xs) with f x
... | true = x ∷ filter′ f xs
... | false = filter′ f xs
thm : {P : Pred ℕ} (n m : ℕ) → P (n + m) → P (m + n)
thm n m p with n + m | +-comm n m
thm n m p | .(m + n) | refl = p
thm′ : {P : Pred ℕ} (n m : ℕ) → P (n + m) → P (m + n)
thm′ {P} n m pr rewrite +-comm n m = pr
thm′′ : {P : Pred ℕ} (n m : ℕ) → P (n + m) → P (m + n)
thm′′ {P} n m p = subst {P = P} (+-comm n m) p
ListT : Set → Set → Set
ListT X B = ⊤ ⊎ (X × B)
module List where
data List (A : Set) : Set where
[] : List A
_∷_ : A → List A → List A
mkList : ListT A (List A) → List A
mkList (inl tt) = []
mkList (inr (a , as)) = a ∷ as
foldr : (ListT A B → B) → List A → B
foldr alg [] = alg (inl tt)
foldr alg (x ∷ xs) = alg (inr (x , foldr alg xs))
list-id : List A → List A
list-id = foldr mkList
incr : ListT A ℕ → ℕ
incr (inl tt) = zero
incr (inr (_ , n)) = suc n
length : List A → ℕ
length = foldr incr
module CoList where
record CoList (A : Set) : Set where
coinductive
field
next : ListT A (CoList A)
open CoList
[] : CoList A
next [] = inl tt
_∷_ : A → CoList A → CoList A
next (x ∷ xs) = inr (x , xs)
unfoldr : (S → ListT A S) → S → CoList A
next (unfoldr coalg s) with coalg s
next (unfoldr coalg s) | inl tt = inl tt
next (unfoldr coalg s) | inr (a , s') = inr (a , unfoldr coalg s')
repeat : A → CoList A
repeat = unfoldr λ x → inr (x , x)
take : ℕ → CoList A → List.List A
take zero xs = List.[]
take (suc n) xs with next xs
take (suc n) xs | inl tt = List.[]
take (suc n) xs | inr (a , xs') = a List.∷ take n xs'
module Stream where
record Stream (A : Set) : Set where
coinductive
field
head : A
tail : Stream A
open Stream
forever : A → Stream A
head (forever x) = x
tail (forever x) = forever x
unfold : (S → A × S) → S → Stream A
head (unfold coalg s) = fst (coalg s)
tail (unfold coalg s) = unfold coalg (snd (coalg s))