Section mon_det. (* For variable discharging. *)
Variables (M: Monad) (T: Set).
Definition filter (c: T -> M bool) (l: list T): M { l': list T | length l' <= length l }.
(* Something with result type  M (list T)  is not good enough, because then   refine (u <- filter ... ; _)   just gives   u: list T, which is useless. *)
Proof with auto with arith.
induction l.
refine (ret (exist _ nil _))...
refine (
b <- c a ;
t <- IHl ;
ret (if b then exist _ (a :: proj1_sig t) _ else exist _ (proj1_sig t) _)
); simpl; destruct t...
Defined.

Lemma hm (e: extMonad M) c l: forall U (f: list T -> M U) g,
ext_eq g (f ∘ @proj1_sig _ _) -> filter c l >>= g = filterM c l >>= f.