Your code can be read as
let () = (* I expect an unit result *)
try int_of_string "4"
(* if the call to `int_of_string` succeeds returns this result,
which is an int *)
with (* otherwise if an exception was raised* *)
| Failure ->
(* returns 1 if the raised exception was the `Failure` exception *)
-1
| n -> n (* otherwise returns the exception `n` *)
which fails due to a lot of small paper cuts. The corrected version would be
let n =
try int_of_string "4" with
| Failure _ (* Failure contains a error message as an argument *) -> - 1
Nevertheless, I would suggest to use the match ... with exception ... -> ... construct which may be closer to your intuition
let n = match int_of_string "4" with
| exception Failure _msg -> -1
| x -> x (* if there was no exception, returns the result *)
but you can also avoid the exception with
let n = match int_of_string_opt "4" with
| None -> -1
| Some x -> x
or even
let n = Option.value ~default:(-1) (int_of_string_opt "4")