83 lines
1.9 KiB
Text
83 lines
1.9 KiB
Text
inductive Foo where
|
|
| foo : (String → Option Foo) → Foo
|
|
|
|
-- Would be great if this worked, but it doesn't yet:
|
|
|
|
/--
|
|
error: failed to infer structural recursion:
|
|
Cannot use parameter #2:
|
|
failed to eliminate recursive application
|
|
map m x
|
|
-/
|
|
#guard_msgs in
|
|
def Foo.map (m : Foo → Foo) : Foo → Foo
|
|
| .foo f => .foo fun s => match f s with
|
|
| none => none
|
|
| some x => map m x
|
|
termination_by structural x => x
|
|
|
|
-- workaround:
|
|
|
|
mutual
|
|
def Foo.bar (m : Foo → Foo) : Foo → Foo
|
|
| .foo f => .foo fun s => Foo.bar_aux m (f s)
|
|
termination_by structural x => x
|
|
|
|
def Foo.bar_aux (m : Foo → Foo) : Option Foo → Option Foo
|
|
| none => none
|
|
| some x => bar m x
|
|
termination_by structural x => x
|
|
end
|
|
|
|
-- similar
|
|
|
|
/--
|
|
error: failed to infer structural recursion:
|
|
Cannot use parameter xs:
|
|
failed to eliminate recursive application
|
|
g ys
|
|
-/
|
|
#guard_msgs in
|
|
def g (xs : List Nat) : Nat :=
|
|
match xs with
|
|
| [] => 0
|
|
| _::ys =>
|
|
match ys with
|
|
| [] => 1
|
|
| _::_::zs => g zs + 1
|
|
| _zs => g ys + 2
|
|
termination_by structural xs
|
|
|
|
|
|
inductive Foo2 where
|
|
| none
|
|
| foo : (String → Foo2) → Foo2
|
|
|
|
/--
|
|
error: failed to infer structural recursion:
|
|
Cannot use parameter #2:
|
|
failed to eliminate recursive application
|
|
map m (f₂ s)
|
|
-/
|
|
#guard_msgs in
|
|
def Foo2.map (m : Foo2 → Foo2) : Foo2 → Foo2
|
|
| none => none
|
|
| .foo f => .foo fun s => match f s with
|
|
| none => none
|
|
| foo f₂ => .foo fun s => map m (f₂ s)
|
|
termination_by structural x => x
|
|
|
|
|
|
/--
|
|
error: failed to infer structural recursion:
|
|
Cannot use parameter #2:
|
|
failed to eliminate recursive application
|
|
map_tricky m (f₂ s)
|
|
-/
|
|
#guard_msgs in
|
|
def Foo2.map_tricky (m : Foo2 → Foo2) : Foo2 → Foo2
|
|
| none => none
|
|
| .foo f => .foo fun s => match f s, f (s ++ s) with
|
|
| foo f₂, foo f₃ => .foo fun s => if s = "test" then map_tricky m (f₂ s) else map_tricky m (f₃ s)
|
|
| _, _ => none
|
|
termination_by structural x => x
|