The Sum Type
Learning Objectives
- You know the sum type terms (
inl,inr, andscase) and their intended meaning. - You can derive and implement typing rules for sums.
- You can implement call-by-value reduction rules for injections and sum case matching.
Introduction
Sum types, as you already know from chapter 1 are useful for lots of situations. For example, when we want a variable to hold one of many different types, we could express that using sum types.
The dynamics of sum types are straight-forward. We reduce injection terms until they are values. Sum case matching reduces the scrutinee and once itβs an injection, it reduces to the corresponding branch. The types in the injection are not used after type checking so we ignore them (by blanketing them with underscores) during the reduction rules.
The rules should seem familiar, because they are very closely related to natural numbers (compare with CaseNat for example).
Typing rules for sums are as follows.
Again, the CaseSum typing rule reminds us of the CaseNat rule.
Injections, Case Matching and The Sum Type
0 / 90 points
Implement type inference and call-by-value reduction for injections and sum case matching as described in the materials.
Note: the macro is brittle with parsing sums, add parentheses around (Bool + Bool) to make sure itβs parsed correctly.
Implement Example Terms
Implement the following terms as top-level functions:
| Function | Type | Description |
|---|---|---|
swap | (Bool + (Bool + Bool)) β ((Bool + Bool) + Bool) | Swaps the left and right in the sum. |
forward | (Bool β Bool) β (Bool + Bool) | Forward direction of an equivalence between Bool β Bool and Bool + Bool. |
backward | (Bool + Bool) β (Bool β Bool) | Backward direction of an equivalence between Bool β Bool and Bool + Bool. |
forward and backward should be inverses of each other, but only forward after backward, i.e. the identity on Bool + Bool can be tested easily.
Comparing two functions of type Bool β Bool requires comparing them one input at a time.
Note: there are many correct solutions to forward and backward.
Hints for forward and backward:
forward: call the argumentf : Bool -> Bool. Now leta = f trueandb = f false.- If
a = true, then returninl bwith a suitable right-hand type - If
a = false, then returninr bwith a suitable left-hand type
- If
backward: call the arguments : Bool + Bool.- If
s = inl l _, then returnfun b : Bool, if b then True else l - If
s = inr r _, then returnfun b : Bool, if b then False else r
- If
Try defining the forward and backward functions in STLC++ first to ensure you have right logic.
Grading
- Only
infer_typeis tested, the individual typing rules are not. - Only
step_cbvandmultistep_cbvare tested, the individual reduction rules are not. - Only the composition of
forwardafterbackwardis tested for correct behavior. The behavior is tested only viamultistep_cbv. The terms can be defined in various different, but correct ways. - The example terms are tested for correct typing.