(* pair is already defined as we want *)
(* cons is already defined as we want *)
Definition triple {A B C:Type} (x:A*B) (c:C) := (fst x,snd x,c):A*B*C.Notation "ma >>+ mb" := (Mmap2 pair ma mb) (at level 15, left associativity):monad_scope.Notation "mab >>++ mc" := (Mmap2 triple mab mc) (at level 15, left associativity):monad_scope.Notation "mx >>:: mxs" :=  (Mmap2 cons mx mxs) (at level 15, left associativity):monad_scope.

(* Specifications: *)
Lemma Mpair_on_first {A B:Type} (ma:monad A) (mb:monad B) (P:A→Prop): (∀ st, P (snd (ma st))) → ∀ st, P (fst (snd ((ma >>+ mb) st))).
Lemma Mtriple_on_all {A:Type} (m1 m2 m3:monad A) (P:A→Prop): (∀ st, P (snd (m1 st))) → (∀ st, P (snd (m2 st))) → (∀ st, P (snd (m3 st))) → ∀ st, P (fst (fst (snd ((m1>>+m2>>++m3) st)))) ∧ P (snd (fst (snd ((m1>>+m2>>++m3) st)))) ∧ P (snd (snd ((m1>>+m2>>++m3) st))).
Lemma Mcons_forall {A:Type} (m:monad A) (ms:monad (list A)) (P:A→Prop): (∀ st, P (snd (m st))) → (∀ st, Forall P (snd (ms st))) → ∀ st, Forall P (snd ((m >>:: ms) st)).