| structure ListZipper (α : Type) := | |
| (xs : List α) (bs : List α) | |
| -- set_option trace.compiler.ir.rc true | |
| variable {α : Type} | |
| namespace ListZipper | |
| def goForward : ListZipper α → ListZipper α | |
| | ⟨[], bs⟩ => ⟨[], bs⟩ | |
| | ⟨x::xs, bs⟩ => ⟨xs, x::bs⟩ | |
| def goBackward : ListZipper α → ListZipper α | |
| | ⟨xs, []⟩ => ⟨xs, []⟩ | |
| | ⟨xs, b::bs⟩ => ⟨b::xs, bs⟩ | |
| def insert : ListZipper α → α → ListZipper α | |
| | ⟨xs, bs⟩, x => ⟨xs, x::bs⟩ | |
| def erase : ListZipper α → ListZipper α | |
| | ⟨[], bs⟩ => ⟨[], bs⟩ | |
| | ⟨x::xs, bs⟩ => ⟨xs, bs⟩ | |
| def curr [Inhabited α] : ListZipper α → α | |
| | ⟨[], bs⟩ => default | |
| | ⟨x::xs, bs⟩ => x | |
| def currOpt : ListZipper α → Option α | |
| | ⟨[], bs⟩ => none | |
| | ⟨x::xs, bs⟩ => some x | |
| def toList : ListZipper α → List α | |
| | ⟨xs, bs⟩ => bs.reverse ++ xs | |
| def atEnd (z : ListZipper α) : Bool := | |
| z.xs.isEmpty | |
| end ListZipper | |
| def List.toListZipper (xs : List α) : ListZipper α := | |
| ⟨xs, []⟩ | |
| partial def testAux : ListZipper Nat → ListZipper Nat | |
| | z => | |
| if z.atEnd then | |
| z | |
| else if z.curr % 2 == 0 then | |
| testAux (z.goForward.insert 0) | |
| else if z.curr > 20 then | |
| testAux z.erase | |
| else | |
| testAux z.goForward -- testAux z.goForward | |
| def test (xs : List Nat) : List Nat := | |
| (testAux xs.toListZipper).toList | |
| #eval (IO.println (test [10, 11, 13, 20, 22, 40, 41, 11]) : IO Unit) |