definition example program

The list type (list of ) is defined by two introduction rules

(“a list is either empty or a thing followed by a list of things”) and the elimination rule: given and there is a unique with and . Such an is a fold (list catamorphism); in Haskell foldr step init, with [a], [] and (:) as built-in syntax.

1Laa£Laca£cNilinithConsida£hstep1Laa£Laca£cNilinithConsida£hstep

Sources: DaoFP §7.2 (“Lists”, “Elimination Rule”), §7.3 (“Functoriality”: map, badMap), §12.4 (“Lists as initial algebras”), §15.3 (“Free monoid and the list monad”), Exercises 7.2.1–7.2.3; Kittenlab Lecture 5 (ConcatMonoid); 7 Sketches §5.2.4 (free monoid); CTfS Definition 3.1.1.10, Example 3.1.1.11

  • Lists as functions (CTfS Definition 3.1.1.10): a list in is a pair with its length and its entries; concatenation uses on and after — so and is the unit.
  • Functoriality (§7.3): for , map f is the fold with and . The alternative (badMap, which drops all elements) type-checks but fails the functor law map id = id — see Functor.
  • is the Free Monoid on and the Initial Algebra of ; foldr is the catamorphism. (Natural Numbers Object, DaoFP Exercise 7.2.1).
  • Not every mapping out of a list is a fold, but every Haskell function [a] -> c written by pattern matching on [] and (:) is (DaoFP Exercise 7.2.2, DaoFP Exercise 7.2.3).
  • sum = foldr plus Z on lists of naturals; the List Monad uses concatenation as join.

Docs: Kittenlab Lecture 5

# foldr as the list recursor
recList(init, step) = as -> isempty(as) ? init : step(as[1], recList(init, step)(as[2:end]))
recList(0, +)([1, 2, 3])                      # 6
mapList(f) = recList(Any[], (a, bs) -> [f(a); bs])
mapList(x -> x^2)([1, 2, 3])                  # [1, 4, 9]
third(as) = length(as) >= 3 ? Some(as[3]) : nothing
import Mathlib
#check @List.rec                -- the eliminator
#check @List.foldr              -- (α → β → β) → β → List α → β
#check @List.map
#check @List.map_id             -- the functor law badMap violates
#check @List.get?               -- l.get? 2 : Option α, the "third element" of Exercise 7.2.3
data List a where
  Nil  :: List a
  Cons :: (a, List a) -> List a
 
recList :: c -> ((a, c) -> c) -> (List a -> c)       -- the list recursor
recList init step = \as -> case as of
  Nil          -> init
  Cons (a, as) -> step (a, recList init step as)
 
foldr' :: (a -> c -> c) -> c -> [a] -> c              -- built-in lists
foldr' step init = \as -> case as of
  []     -> init
  a : as -> step a (foldr' step init as)
 
mapList :: (a -> b) -> List a -> List b
mapList f = recList Nil (\(a, bs) -> Cons (f a, bs))