RESULT = struct

  type ('a, 'b) t = [
    | `Ok of 'a
    | `Error of 'b
  ]

  let return a  = `Ok a
  let fail b = `Error b

  let bind x f =
    match x with
    | `Ok x -> f x
    | `Error e -> fail e

  let (>>=) = bind

  let map x f =
    match x with
    | `Ok x -> return (f x)
    | `Error e -> fail e

  let (>>|) = map

  let destruct (#as t) f = f t
  let (>><) = destruct
end