I’m on board with giving the programmer a hint that a function might fail, but how do you avoid contaminating the type of other functions? An immediate failwith
?
In the following code, f1
and f2
return an Or_error.t
even though their caller can do nothing to prevent it. Now our codebase has 3 functions whose return types tell the programmer to be careful but there’s nothing to be careful about when calling the last two.
let divide a b =
if b = 0 then
Error (Error.of_string "Division by zero")
else
Ok (a / b)
let f1 () =
divide 0 0
let f2 () =
f1 ()
So, the way I’d write my code is:
let divide a b =
if b = 0 then
Error (Error.of_string "Division by zero")
else
Ok (a / b)
let f1 () =
match divide 0 0 with
| Ok x -> x
| Error e -> Error.raise e
let f2 () =
f1 ()
Now both f1
and f2
return a plain int
and the programmer’s attention is drawn to divide
. Is this recommended usage, as opposed to monadic propagation?