The List Type
Learning Objectives
- You know the core terms and typing rules for lists in STLC.
- You know the call-by-value reduction rules for list constructors and list case matching.
- You can implement list typing and dynamics by following the same pattern as products and sums.
Introduction
Lists are a recursive algebraic data type with two constructors: an empty list and a non-empty list built from a head and a tail. As with sums and natural numbers, we add both syntax and operational rules to the calculus.
The dynamics of lists are closely related to products and sums:
we first reduce inside constructors, and when the scrutinee becomes canonical (nil or cons), the matching rule applies.
Typing rules for lists follow the same structure:
nil(T)has type[T].cons(h, t)has type[T]ifh : Tandt : [T].- In
lcase, both branches must produce the same result type.
As with CaseNat and CaseSum, the branch term in CaseList is encoded as an abstraction.
This keeps the core syntax small while still giving us expressive case analysis.
Primitive Recursion on Lists
To define useful recursive list functions (such as append, map, and all) we add a list recursor.
As with lcase, the call-by-value semantics evaluates only the scrutinee before choosing a branch.
In Rust code, this constructor is called RecList.
Lists, Case Matching and Primitive Recursion
0 / 100 points
Implement type inference and call-by-value reduction for list terms as described in the materials.
This pack is fully standalone. Do not depend on earlier exercise packs.
Implement Core Rules
Extend typing and reduction with the list constructors and eliminators:
Nil(T)Cons(head, tail)CaseList { scrutinee, if_nil, if_cons }RecList { scrutinee, if_nil, if_cons }
Implement Example Terms
Implement the following top-level functions.
| Function | Type | Description |
|---|---|---|
is_empty | [Bool] -> Bool | Returns True on Nil, otherwise False. |
head_or_false | [Bool] -> Bool | Returns the head if non-empty, otherwise False. |
append | [Bool] -> [Bool] -> [Bool] | Appends two lists (use RecList). |
negate_all | [Bool] -> [Bool] | Maps boolean negation over the list. |
all_true | [Bool] -> Bool | Returns True iff all elements are True. |
Grading
- Only
infer_typeis tested, the individual typing-rule helper methods are not tested directly. - Only
step_cbvandmultistep_cbvare tested, the individual reduction helper methods are not tested directly. - The example terms are tested for both typing and behavior.
- The behavior tests run through
multistep_cbvand accept any semantically correct implementation.