If you write
let try_finalize f g y x = try g (f x) with _ -> y
Your function will return y
if f
doesn't raise an error but g
does, which is not what you said you want.
To ensure that you catch only errors from f
you should put f x
alone in the try block:
let try_finalize f g y x =
let z = try Some (f x) with _ -> None in
match z with
| Some z -> g z
| None -> y
Exceptions may be considered bad style in a purely functional code, that's why you may want to transform a function that may raise an exception such as List.assoc : 'a -> ('a * 'b) list -> 'b
into a function that does the same thing but returns an option.
That's what
let with_option f = try_finalize f (fun x-> Some x) None
does.