apply (vec_sorted_impl _ H).
apply isort_sorts.
Qed.
End plain.
End plain.
Module pairs.
Section pairs.
Variables (T: Set) (le: T -> T -> bool).
Fixpoint insert (l: list T) (x: T) {struct l}: nat * list T :=
match l with
| nil => (0, x :: nil)
| h :: t =>
if le x h
then (1, x :: h :: t)
else let (n, t') := insert t x in (S n, h :: t')
end.
Fixpoint insert_many (l l': list T) {struct l'}: nat * list T :=
match l' with
| nil => (0, l)
| h :: t =>
let (n, u) := insert l h in
let (m, v) := insert_many u t in
(n + m, v)
end.
Definition isort: list T -> (nat * list T) := insert_many nil.
End pairs.
End pairs.
Eval compute in (pairs.isort leb numbers).
Module monadic.
Section monadic.
Variables (M: Monad) (T: Set) (le: T -> T -> M bool).
Fixpoint insert (l: list T) (x: T): M (list T) :=
match l with
| nil => ret (x :: nil)
| h :: t =>
r <- le x h ;
if r
then ret (x :: h :: t)
else t' <- insert t x ; ret (h :: t')
end.

(* Specifications: *)
Lemma insert_unfold: forall l x, insert l x =
match l with
| nil => ret (x :: nil)
| h :: t =>
r <- le x h ;
if r then ret (x :: h :: t) else t' <- insert t x ; ret (h :: t')
end.