Module Notations.
Delimit Scope io_scope with io.
Notation "c >>= f" := (bind c f)
(at level 50, left associativity) : io_scope.
Notation "f =<< c" := (bind c f)
(at level 51, right associativity) : io_scope.
Notation "x <- c1 ;; c2" := (bind c1 (fun x => c2))
(at level 100, c1 at next level, right associativity) : io_scope.
Notation "e1 ;; e2" := (_ <- e1%io ;; e2%io)%io
(at level 100, right associativity) : io_scope.
Notation delay io := (delay_io (fun _ => io)).
Open Scope io_scope.
End Notations.
(** ** Equations *)
(** *** Monad laws *)

Axiom ret_bind : forall {a} (m : IO a), bind m ret = m.
Axiom bind_bind :
forall {a b c} (m : IO a) (k : a -> IO b) (h : b -> IO c),
bind (bind m k) h = bind m (fun x => bind (k x) h).