module type Monad = sig type 'a t val return : 'a -> 'a t val bind : 'a t -> ('a -> 'b t) -> 'b t end module type FullMonad = sig type 'a t val return : 'a -> 'a t val bind : 'a t -> ('a -> 'b t) -> 'b t val (>>=) : 'a t -> ('a -> 'b t) -> 'b t val (let*) : 'a t -> ('a -> 'b t) -> 'b t val join : 'a t t -> 'a t end module Expand (M : Monad) = struct include M let (>>=) = M.bind let (let*) = M.bind let join m = M.bind m (fun m -> m) end