exercise 24.1.
If the raw source computations are stored in the operation tag, the catch component must be polymorphic in the result type of the whole folded tree. Its shape is 𝑎𝖼𝖺𝗍𝖼𝗁:𝖲𝗒𝗇𝗍𝖺𝗑𝐻(𝐴)×𝖲𝗒𝗇𝗍𝖺𝗑𝐻(𝐴)⟶(𝐴⟶𝐺(𝐵))⟶𝐺(𝐵). The continuation has already been folded, but the two arguments still have type 𝖲𝗒𝗇𝗍𝖺𝗑𝐻(𝐴), not 𝐺(𝐴). To use them, the component would need an additional polymorphic argument 𝜏𝑋:𝖲𝗒𝗇𝗍𝖺𝗑𝐻(𝑋)⟶𝐺(𝑋)for every 𝑋. This is a translator for the complete source signature 𝐻. It cannot be supplied by the catch component alone, because either source computation may contain any operation of 𝐻. Adding a new summand to 𝐻 therefore changes the argument expected by the catch clause, which is exactly the lost modularity.
exercise 24.2.
Let 𝟑 ={0,1,2}. Define one operation 𝖿𝗂𝗋𝗌𝗍(𝑡) for each 𝑡 :𝖳𝗒, and put 𝖥𝗈𝗋𝗄𝖥𝗂𝗋𝗌𝗍(𝖿𝗂𝗋𝗌𝗍(𝑡))=(𝟑,𝜆𝑖.𝖵𝖺𝗅(𝑡)),𝖱𝖾𝗍𝖧𝖥𝗂𝗋𝗌𝗍(𝖿𝗂𝗋𝗌𝗍(𝑡))=𝖵𝖺𝗅(𝑡). For 𝑀𝑖 :𝖧𝖾𝖿𝗍𝗒𝐻(𝖵𝖺𝗅(𝑡)), the smart constructor is 𝖿𝗂𝗋𝗌𝗍(𝑀0,𝑀1,𝑀2)=𝗂𝗆𝗉𝗎𝗋𝖾(𝖿𝗂𝗋𝗌𝗍(𝑡),𝜓,𝗉𝗎𝗋𝖾), where 𝜓(0)=𝑀0,𝜓(1)=𝑀1,𝜓(2)=𝑀2. Every fork component has the result index demanded by its position, and the operation continuation receives the selected value.
exercise 24.3.
With the correct bind, the branches of 𝐶 remain pure and the continuation is 𝑔. The selected branch returns ⋆, the continuation emits one 𝗍𝗂𝖼𝗄, and 𝗋𝖾𝖺𝖽𝖳𝗂𝖼𝗄𝗌 therefore returns 1: 𝐶≫=𝖧𝑔≫𝖧𝗋𝖾𝖺𝖽𝖳𝗂𝖼𝗄𝗌⟶𝗍𝗂𝖼𝗄≫𝗋𝖾𝖺𝖽𝖳𝗂𝖼𝗄𝗌⟶1. For the structural bind (24.3), the selected branch is first changed from 𝗉𝗎𝗋𝖾( ⋆) to 𝗍𝗂𝖼𝗄, and the node continuation is also 𝑔. After the branch tick returns, the continuation emits the second tick: 𝐶𝖻𝗂𝗇𝖽×𝑔≫𝖧𝗋𝖾𝖺𝖽𝖳𝗂𝖼𝗄𝗌⟶𝗍𝗂𝖼𝗄≫𝗍𝗂𝖼𝗄≫𝗋𝖾𝖺𝖽𝖳𝗂𝖼𝗄𝗌⟶2. Both programs remain well typed. The count exposes the misplaced recursive call.
exercise 24.4.
Expanding the definition through (24.6) gives 𝖿𝗆𝖺𝗉𝖧(𝑓,𝗉𝗎𝗋𝖾(𝑥))=𝗉𝗎𝗋𝖾(𝑓(𝑥)),𝖿𝗆𝖺𝗉𝖧(𝑓,𝗂𝗆𝗉𝗎𝗋𝖾(𝑜,𝜓,𝑘))=𝗂𝗆𝗉𝗎𝗋𝖾(𝑜,𝜓,𝖿𝗆𝖺𝗉𝖧(𝑓,−)∘𝑘). The identity law is the right-unit equation of theorem 24.8: 𝖿𝗆𝖺𝗉𝖧(𝗂𝖽,𝑀)=𝑀≫=𝖧𝗉𝗎𝗋𝖾=𝑀. For composition, associativity and the left unit give 𝖿𝗆𝖺𝗉𝖧(𝑔,𝖿𝗆𝖺𝗉𝖧(𝑓,𝑀))=(𝑀≫=𝖧(𝗉𝗎𝗋𝖾∘𝑓))≫=𝖧(𝗉𝗎𝗋𝖾∘𝑔)=𝑀≫=𝖧(𝜆𝑥.𝗉𝗎𝗋𝖾(𝑓(𝑥))≫=𝖧(𝗉𝗎𝗋𝖾∘𝑔))=𝑀≫=𝖧(𝗉𝗎𝗋𝖾∘𝑔∘𝑓)=𝖿𝗆𝖺𝗉𝖧(𝑔∘𝑓,𝑀).
exercise 24.5.
Work in the fixed-type catch fragment specified in the exercise. Choose 𝑥 ≠𝑦 :𝐴 and a constant 𝑔 :𝐴 ⟶𝖧𝖾𝖿𝗍𝗒𝐻(𝐵), say 𝑔(𝑎) =𝗉𝗎𝗋𝖾(𝑏0). Put 𝐶𝑥=𝖼𝖺𝗍𝖼𝗁(𝗉𝗎𝗋𝖾(𝑥),𝗉𝗎𝗋𝖾(𝑥)),𝐶𝑦=𝖼𝖺𝗍𝖼𝗁(𝗉𝗎𝗋𝖾(𝑦),𝗉𝗎𝗋𝖾(𝑦)). A structural catamorphism with generator 𝑔 presents the same data to its operation algebra in both cases. The operation tag is the same, each folded fork component is 𝑔(𝑥)=𝗉𝗎𝗋𝖾(𝑏0)=𝑔(𝑦), and the folded continuation is 𝑔 in both trees. Hence a fixed component 𝛽𝑔 must return the same result for 𝐶𝑥 and 𝐶𝑦.
Correct bind does not return the same result. Equation (24.3) gives 𝐶𝑥≫=𝖧𝑔=𝗂𝗆𝗉𝗎𝗋𝖾(𝖼𝖺𝗍𝖼𝗁(𝑡),𝜆_.𝗉𝗎𝗋𝖾(𝑥),𝑔),𝐶𝑦≫=𝖧𝑔=𝗂𝗆𝗉𝗎𝗋𝖾(𝖼𝖺𝗍𝖼𝗁(𝑡),𝜆_.𝗉𝗎𝗋𝖾(𝑦),𝑔). Their forks differ because 𝑥 ≠𝑦. Thus no algebra which sees only the recursively folded fields can define hefty bind for every 𝑔.
exercise 24.6.
The source smart constructor has an empty fork. Its operation continuation returns the source response after the transport supplied by the higher-order insertion witness; that transport is definitionally trivial for the front summand. Applying (24.5), then (24.5.1), gives 𝖾𝗅𝖺𝖻𝗈𝗋𝖺𝗍𝖾𝐸𝗅𝗂𝖿𝗍,𝑤(↑𝑜)=𝗂𝗆𝗉𝗎𝗋𝖾(𝜄ℓ𝑤(𝑜),𝗉𝗎𝗋𝖾∘𝑞ℓ𝑤,𝑜). A target response has type 𝑟:𝖱𝖾𝗍Δ(𝜄ℓ𝑤(𝑜)). The transport 𝑞ℓ𝑤,𝑜(𝑟):𝖱𝖾𝗍Δ0(𝑜) converts it to the response expected by the source operation continuation, and 𝗉𝗎𝗋𝖾 returns that response in the target tree.
exercise 24.7.
Correct hefty bind leaves both catch branches unchanged and replaces the catch continuation by 𝑓. After the catamorphism, the clause data are ̂𝜓(𝗍𝗍)=𝗍𝗁𝗋𝗈𝗐,̂𝜓(𝖿𝖿)=𝖾𝗅𝖺𝖻𝗈𝗋𝖺𝗍𝖾𝐸(𝑀),̂𝑘=𝖾𝗅𝖺𝖻𝗈𝗋𝖺𝗍𝖾𝐸∘𝑓. Put 𝑁=𝖾𝗅𝖺𝖻𝗈𝗋𝖺𝗍𝖾𝐸(𝑀),𝐾=𝖾𝗅𝖺𝖻𝗈𝗋𝖺𝗍𝖾𝐸∘𝑓. Substitution into (24.18) yields 𝗆𝖺𝗌𝗄(𝗋𝗎𝗇𝖳𝗁𝗋𝗈𝗐(𝗍𝗁𝗋𝗈𝗐))≫=𝗆𝖺𝗒𝖻𝖾(𝐾,𝑁≫=𝐾)=𝗉𝗎𝗋𝖾(𝗇𝗈𝗇𝖾)≫=𝗆𝖺𝗒𝖻𝖾(𝐾,𝑁≫=𝐾)=𝑁≫=𝐾. The translated continuation occurs once, as the continuation sequenced after the fallback result. It was not pushed into the fallback before the catch clause was interpreted.
exercise 24.8.
The canonical reassociation sends operation tags by 𝗂𝗇𝗅(𝗂𝗇𝗅(𝑜1))↦𝗂𝗇𝗅(𝑜1),𝗂𝗇𝗅(𝗂𝗇𝗋(𝑜2))↦𝗂𝗇𝗋(𝗂𝗇𝗅(𝑜2)),𝗂𝗇𝗋(𝑜3)↦𝗂𝗇𝗋(𝗂𝗇𝗋(𝑜3)). Its inverse is determined by reversing these three equations. The fork and return families on corresponding tags are definitionally the same component families, so transport changes only the nested sum tag.
For 𝑜1, both composite algebras dispatch to 𝐸1; for 𝑜2, both dispatch to 𝐸2; for 𝑜3, both dispatch to 𝐸3. In every case the fork and continuation arguments are passed through unchanged. Hence the algebras agree after transport along reassociation.
Without transport, the left algebra has domain (𝐻1 ⊞𝐻2) ⊞𝐻3, while the right algebra has domain 𝐻1 ⊞(𝐻2 ⊞𝐻3). Literal equality would compare terms of different types.
exercise 24.9.
The alternative component retains only the protected branch and sequences its result into the operation continuation. For (24.8), that continuation is the translation of 𝗀𝖾𝗍. Thus 𝖾𝗅𝖺𝖻𝗈𝗋𝖺𝗍𝖾𝐸𝗉𝗋𝗈𝗍𝖾𝖼𝗍𝖾𝖽(𝗍𝗋𝖺𝗇𝗌𝖺𝖼𝗍)=𝗉𝗎𝗍(1)≫((𝗉𝗎𝗍(2)≫𝗍𝗁𝗋𝗈𝗐)≫=(𝜆_.𝗀𝖾𝗍))=𝗉𝗎𝗍(1)≫𝗉𝗎𝗍(2)≫𝗍𝗁𝗋𝗈𝗐. The last equality uses the empty response type of throw: no continuation branch can reach get. The state handler, started at zero, performs 0 ↦1 ↦2 and then forwards the throw. The outer throw handler maps that node to 𝗇𝗈𝗇𝖾. The final state is not returned by the chosen state handler, but the update to 2 occurs before the abort.
exercise 24.10.
For 𝑆 :𝖥𝗋𝖾𝖾𝜀(𝖬𝖺𝗒𝖻𝖾(𝐴)), define 𝑞𝑆=𝗆𝖺𝗒𝖻𝖾(𝗉𝗎𝗋𝖾∘𝗌𝗈𝗆𝖾,𝑆). Then (24.29) says that observable catch is 𝐶(𝑅,𝑆) =𝑅≫=𝑞𝑆. Hence 𝐶(𝐶(𝑅1,𝑅2),𝑅3)=(𝑅1≫=𝑞𝑅2)≫=𝑞𝑅3=𝑅1≫=(𝜆𝑧.𝑞𝑅2(𝑧)≫=𝑞𝑅3). If 𝑧 =𝗌𝗈𝗆𝖾(𝑥), the function in the last line returns 𝗉𝗎𝗋𝖾(𝗌𝗈𝗆𝖾(𝑥)). If 𝑧 =𝗇𝗈𝗇𝖾, it returns 𝑅2≫=𝑞𝑅3 =𝐶(𝑅2,𝑅3). Therefore it is pointwise 𝑞𝐶(𝑅2,𝑅3), and 𝐶(𝐶(𝑅1,𝑅2),𝑅3)=𝐶(𝑅1,𝐶(𝑅2,𝑅3)). Substitute 𝑅𝑖 =𝗋𝗎𝗇(𝑀𝑖) and apply (24.29) in both directions. The proof concerns observed results; the two nested source trees have different constructor shapes.
exercise 24.11.
This is exactly theorem 24.13.
This is a clause of theorem 24.30, not a consequence of typing alone.
Neither theorem supplies it. One needs a source operational semantics, a target step relation modulo administrative equations, and a simulation relation.
Neither theorem supplies it. One needs a closed-program effect invariant and a progress or handler-completeness theorem for the target.
Neither theorem supplies it. One needs a surface elaboration or typechecking algorithm and a soundness theorem relating its output to 𝖧𝖾𝖿𝗍𝗒𝐻.
exercise 24.12.
Write 𝑚𝑖 =̂𝜓(𝑖) and let ℎ =𝗋𝗎𝗇𝖳𝗁𝗋𝗈𝗐𝑤. Put 𝑟𝑖=𝗆𝖺𝗌𝗄𝑤(ℎ(𝑚𝑖)). A left-to-right component is 𝐸𝖿𝗂𝗋𝗌𝗍(𝖿𝗂𝗋𝗌𝗍(𝑡),̂𝜓,̂𝑘)=𝑟0≫=𝗆𝖺𝗒𝖻𝖾(̂𝑘,𝑟1≫=𝗆𝖺𝗒𝖻𝖾(̂𝑘,𝑟2≫=𝗆𝖺𝗒𝖻𝖾(̂𝑘,𝗍𝗁𝗋𝗈𝗐))). Each 𝑚𝑖 has type 𝖥𝗋𝖾𝖾Δ(𝖵𝖺𝗅(𝑡)). Therefore ℎ(𝑚𝑖):𝖥𝗋𝖾𝖾Δ′(𝖬𝖺𝗒𝖻𝖾(𝖵𝖺𝗅(𝑡))) and 𝗆𝖺𝗌𝗄𝑤(ℎ(𝑚𝑖)):𝖥𝗋𝖾𝖾Δ(𝖬𝖺𝗒𝖻𝖾(𝖵𝖺𝗅(𝑡))). The continuation has type ̂𝑘 :𝖵𝖺𝗅(𝑡) ⟶𝖥𝗋𝖾𝖾Δ(𝐴), while the innermost target throw has type 𝖥𝗋𝖾𝖾Δ(𝐴). Hence every 𝗆𝖺𝗒𝖻𝖾 is a function from 𝖬𝖺𝗒𝖻𝖾(𝖵𝖺𝗅(𝑡)) to 𝖥𝗋𝖾𝖾Δ(𝐴), and every displayed bind returns 𝖥𝗋𝖾𝖾Δ(𝐴).
On the given input, handling the first branch produces 𝗉𝗎𝗋𝖾(𝗇𝗈𝗇𝖾), so evaluation continues to the second. The second branch produces 𝗉𝗎𝗋𝖾(𝗌𝗈𝗆𝖾(2)). Hence its 𝗆𝖺𝗒𝖻𝖾 invokes ̂𝑘(2). For the smart constructor, ̂𝑘 =𝗉𝗎𝗋𝖾, so the result is 𝗉𝗎𝗋𝖾(2). The third branch is not inserted into the target tree.
exercise 24.13.
Let ℎ =𝗋𝗎𝗇𝖳𝗁𝗋𝗈𝗐𝑤 and let 𝗆𝖺𝗌𝗄𝑤 be the masking map of equation 24.2. Let 𝗍𝗁𝗋𝗈𝗐 denote the target throw tree. The required induction predicate is 𝑃(𝑚):ℎ(𝗆𝖺𝗌𝗄𝑤(ℎ(𝑚))≫=𝗆𝖺𝗒𝖻𝖾(𝗉𝗎𝗋𝖾,𝗍𝗁𝗋𝗈𝗐))=ℎ(𝑚). This is the target equality obtained by expanding 𝗋𝗎𝗇(𝖼𝖺𝗍𝖼𝗁(𝑀,𝗍𝗁𝗋𝗈𝗐𝖧)).
If 𝑚 =𝗉𝗎𝗋𝖾(𝑥), then ℎ(𝑚)=𝗉𝗎𝗋𝖾(𝗌𝗈𝗆𝖾(𝑥)). The masked tree binds through the some branch to 𝗉𝗎𝗋𝖾(𝑥). The outer handler returns the displayed value, which is ℎ(𝑚).
If 𝑚 =𝗍𝗁𝗋𝗈𝗐, then ℎ(𝑚) =𝗉𝗎𝗋𝖾(𝗇𝗈𝗇𝖾). The maybe function selects target throw, and the outer handler returns 𝗉𝗎𝗋𝖾(𝗇𝗈𝗇𝖾) =ℎ(𝑚).
If 𝑚 =𝗂𝗆𝗉𝗎𝗋𝖾(𝑜,𝑘) for a residual operation 𝑜, then the inner handler, masking, bind, and outer handler all forward 𝑜. The left side of (B.1) is 𝗂𝗆𝗉𝗎𝗋𝖾(𝑜,𝜆𝑟.ℎ(𝗆𝖺𝗌𝗄𝑤(ℎ(𝑘(𝑟)))≫=𝗆𝖺𝗒𝖻𝖾(𝗉𝗎𝗋𝖾,𝗍𝗁𝗋𝗈𝗐))), while the right side is 𝗂𝗆𝗉𝗎𝗋𝖾(𝑜,ℎ ∘𝑘). They agree pointwise by the induction hypothesis.
This direct proof fuses three traversals into one induction predicate. The factorized chapter proof isolates handler–bind distribution. It also isolates handler–mask interaction, then obtains catch–throw2 from the ordinary right-unit law. The direct proof is shorter for this law; the factorized proof also supplies observable catch and congruence.
exercise 24.14.
The catch calculation is independent of the final-state observation. By (24.8), both runs receive the same target tree 𝑇𝗍𝗋, where 𝑇𝗍𝗋:=𝗉𝗎𝗍(1)≫𝗉𝗎𝗍(2)≫𝗀𝖾𝗍. The discard-state equations of (24.4) give 𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾0(𝑇𝗍𝗋)=𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾1(𝗉𝗎𝗍(2)≫𝗀𝖾𝗍)=𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾2(𝗀𝖾𝗍)=𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾2(𝗉𝗎𝗋𝖾(2))=𝗉𝗎𝗋𝖾(2). The outer throw handler therefore returns 𝗉𝗎𝗋𝖾(𝗌𝗈𝗆𝖾(2)), and empty-signature elimination yields 𝗌𝗈𝗆𝖾(2).
The pair-returning handler takes the same two state transitions and the same get response. Only its pure equation differs: 𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾×0(𝑇𝗍𝗋)=𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾×1(𝗉𝗎𝗍(2)≫𝗀𝖾𝗍)=𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾×2(𝗀𝖾𝗍)=𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾×2(𝗉𝗎𝗋𝖾(2))=𝗉𝗎𝗋𝖾(2,2). After 𝗋𝗎𝗇𝖳𝗁𝗋𝗈𝗐 and empty-signature elimination, the result is 𝗌𝗈𝗆𝖾(2,2). Both handlers observe the committed update 0 ↦1 ↦2; the second merely exposes the final store. Thus the comparison changes the result interface, not the catch elaborator or its rollback policy.
exercise 24.15.
Represent a parenthesized sum by a binary tree whose leaves are the ordered signatures [𝐻1,…,𝐻𝑛]. Define 𝖿𝗅𝖺𝗍𝗍𝖾𝗇 by concatenating the leaf lists. An operation tag in the tree determines a unique leaf index 𝑖 and a component operation 𝑜 :𝖮𝗉𝖧𝐻𝑖: descend left or right according to its sum injections and count the leaves skipped on right descents. Conversely, a leaf index and component operation rebuild a unique tag by following the tree. These maps are inverse by induction on the binary tree.
Transport the fork and return families by the same recursion. At a leaf they are the component families. At an internal node, a left or right tag reduces to the corresponding child family, so transport introduces no new data beyond the equality identifying the selected leaf.
Now associate to each ordered list of elaborators [𝐸1,…,𝐸𝑛] the flattened dispatcher which sends leaf index 𝑖 to 𝐸𝑖. Induction on either parenthesization shows that its iterated ⋎-composition transports to this dispatcher. Hence any two parenthesizations agree after both are transported to the common flattened signature.
A permutation changes the leaf index assigned to an operation. Proving invariance under it requires an explicit permutation of operation tags and a corresponding reordering of component elaborators. Reassociation preserves the ordered list and therefore cannot supply that theorem.
exercise 24.16.
Abbreviate E(𝑀):=𝖾𝗅𝖺𝖻𝗈𝗋𝖺𝗍𝖾𝐸𝗍𝗋(⌈𝑀⌉),𝑇𝑠(𝑀):=𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾𝑠(E(𝑀)),𝐹𝑁:=𝗆𝖺𝗒𝖻𝖾(𝗉𝗎𝗋𝖾,E(𝑁)). Write ⟨𝑠,𝑀⟩𝑅𝑇⟺𝑇=adm𝑇𝑠(𝑀), where =adm is generated by the free-monad units and associativity together with the displayed handler and mask equations. The five source roots have the following nonempty target calculations. For return sequencing, preservation of source bind by the catamorphism and target left unit give the following result. The embedding clauses used here are E(𝗀𝖾𝗍(𝑥.𝑀))=𝗀𝖾𝗍≫=(𝜆𝑥.E(𝑀)),E(𝑀;𝑁)=E(𝑀)≫E(𝑁). Thus get consumes its returned value by bind, whereas source sequencing discards its left result. The return calculation is 𝑇𝑠(𝗋𝖾𝗍𝗎𝗋𝗇(𝑛);𝑀)𝑒𝑚𝑏𝑒𝑑𝑑𝑖𝑛𝑔/𝑒𝑙𝑎𝑏𝑜𝑟𝑎𝑡𝑖𝑜𝑛=𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾𝑠(𝗉𝗎𝗋𝖾(𝑛)≫=(𝜆_.E(𝑀)))𝑢𝑛𝑖𝑡=𝑇𝑠(𝑀).
For put, 𝑇𝑠(𝗉𝗎𝗍(𝑛);𝑀)𝑒𝑙𝑎𝑏𝑜𝑟𝑎𝑡𝑖𝑜𝑛=𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾𝑠(𝗉𝗎𝗍(𝑛)≫E(𝑀))𝑝𝑢𝑡=𝑇𝑛(𝑀). For get, 𝑇𝑠(𝗀𝖾𝗍(𝑥.𝑀))𝑒𝑙𝑎𝑏𝑜𝑟𝑎𝑡𝑖𝑜𝑛=𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾𝑠(𝗀𝖾𝗍(𝑥.E(𝑀)))𝑔𝑒𝑡=𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾𝑠(E(𝑀)[𝑠/𝑥])𝑠𝑢𝑏𝑠𝑡𝑖𝑡𝑢𝑡𝑖𝑜𝑛=𝑇𝑠(𝑀[𝑠/𝑥]). Thus the last tree is related to ⟨𝑠,𝑀[𝑠/𝑥]⟩.
For a successful catch, the pure equation of the throw handler is 𝗋𝗎𝗇𝖳𝗁𝗋𝗈𝗐(𝗉𝗎𝗋𝖾(𝑛))=𝗉𝗎𝗋𝖾(𝗌𝗈𝗆𝖾(𝑛)). Masking and target bind then select the success continuation: 𝑇𝑠(𝖼𝖺𝗍𝖼𝗁(𝗋𝖾𝗍𝗎𝗋𝗇(𝑛),𝑁))𝑐𝑎𝑡𝑐ℎ=𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾𝑠(𝗉𝗎𝗋𝖾(𝗌𝗈𝗆𝖾(𝑛))≫=𝐹𝑁)𝑗𝑢𝑠𝑡=𝑇𝑠(𝗋𝖾𝗍𝗎𝗋𝗇(𝑛)). For a thrown protected branch, 𝑇𝑠(𝖼𝖺𝗍𝖼𝗁(𝗍𝗁𝗋𝗈𝗐,𝑁))𝑐𝑎𝑡𝑐ℎ=𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾𝑠(𝗆𝖺𝗌𝗄(𝗋𝗎𝗇𝖳𝗁𝗋𝗈𝗐(𝗍𝗁𝗋𝗈𝗐))≫=𝐹𝑁)𝑡ℎ𝑟𝑜𝑤,𝑚𝑎𝑠𝑘=𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾𝑠(𝗉𝗎𝗋𝖾(𝗇𝗈𝗇𝖾)≫=𝐹𝑁)𝑛𝑜𝑡ℎ𝑖𝑛𝑔=𝑇𝑠(𝑁). For completeness, the congruence obligation is the following compatibility lemma, proved by induction on the one-step derivation (sequencing and catch are the two context cases): if ⟨𝑠,𝑃⟩ ⟼𝖧⟨𝑠′,𝑃′⟩, then substituting E(𝑃) by its nonempty admissible calculation to E(𝑃′) inside either the sequencing continuation or the displayed catch context—including 𝗆𝖺𝗌𝗄(𝗋𝗎𝗇𝖳𝗁𝗋𝗈𝗐([ ]))≫=𝐹𝑁—gives the related tree at state 𝑠′. Compatibility of target bind, 𝗋𝗎𝗇𝖳𝗁𝗋𝗈𝗐, mask, and 𝗋𝗎𝗇𝖲𝗍𝖺𝗍𝖾 with their displayed equations proves each induction step; the state parameter changes only in the put case already calculated above. This is the needed lemma, rather than an unstated appeal to ordinary term congruence.
This proves the requested root simulation for the finite grammar. It does not supply surface type inference, a theorem for arbitrary higher-order sums, or absence of unhandled operations in an arbitrary target tree.