let (foldres_of_fold :
     (('a -> 'i -> 'a) -> 'a -> 'v -> 'a) ->
       ('a -> 'i -> ('a, 'e) res) -> 'a -> 'v -> ('a, 'e) res) =
  fun fold f init v ->
    let opt_err = ref None in
    let new_f a v =
      match f a v with
      | `Ok new_a -> new_a
      | `Error e -> (opt_err := Some e; raise Foldres_exit)
    in
      try `Ok (fold new_f init v)
      with
      | Foldres_exit ->
          (match !opt_err with | None -> assert false | Some e -> `Error e)