(DeferredDEFERRED) :
  DEFERRED_RESULT with type 'a deferred = 'Deferred.t
struct

  type 'a deferred = 'Deferred.t
  (* type ('a, 'b) result = ('a, 'b) Result.t *)
  type ('a, 'b) t = ('a, 'b) Result.t Deferred.t

  let return x : (_, _) t = Deferred.return (`Ok x)
  let bind x f =
    Deferred.bind x (function
      | `Error e -> Deferred.return (`Error e)
      | `Ok o -> f o)

  let fail x = Deferred.return (Result.fail x)

  let (>>=) = bind
  let (>><) x f : (_, _) t = Deferred.bind x f

  let map m f =
    m >>= fun x ->
    return (f x)
  let (>>|) = map
  let of_result = Deferred.return


  let catch_deferred f : (_, _) t =
    Deferred.catch
      (fun () ->
         let a_exn_m : 'Deferred.t = f () in
         Deferred.bind a_exn_m (fun x -> Deferred.return (`Ok x)))
      (fun e -> Deferred.return (`Error e))

  let wrap_deferred ~on_exn f =
    let caught = catch_deferred f in
    caught >>< function
    | `Ok o -> return o
    | `Error e -> fail (on_exn e)

  let map_option o ~f =
    begin match o with
    | None -> return None
    | Some s ->
      f s
      >>< begin function
      | `Ok o -> return (Some o)
      | `Error e -> fail e
      end
    end

  let some ~or_fail = function
  | None -> fail or_fail
  | Some s -> return s
  let destruct t f =
    Deferred.bind t (function `Ok o -> f (`Ok o) | `Error e -> f (`Error e))
  let (>><) = destruct

end