inductive Term : Type | const : Nat -> Term | app : List Term -> Term namespace Term instance : Inhabited Term := ⟨Term.const 0⟩ partial def hasToString : Term -> String | const n => "CONST(" ++ toString n ++ ")" | app ts => "APP" instance : HasToString Term := ⟨hasToString⟩ end Term open Term structure MyState : Type := (ts : List Term) def emit (t : Term) : StateM MyState Unit := modify (λ ms => ⟨t::ms.ts⟩) partial def foo : MyState -> Term -> Term -> List Term | ms₀, t, u => let stateT : StateM MyState Unit := do { match t with | const _ => pure () | app _ => emit (const 1) *> pure () ; match t, u with | app _, app _ => emit (app []) *> pure () | _, _ => pure () ; match t, u with | app _, app _ => emit (app []) *> pure () | _, _ => emit (const 2) *> pure () } ; (stateT.run ⟨[]⟩).2.ts.reverse def main : IO Unit := IO.println $ foo ⟨[]⟩ (app []) (app [])