Safe division by zero

A snippet which does a safe division by zero. Can the program be improved.

type safeint =
    | Int of int
    | Nil
let _=
    let myprintint (s:string) (x:int)=
        let _ = print_string (s^":") in
        let _ = print_int x in
        let _ = print_newline () in
        () in
    let safediv1 (x:int) (y:int) : safeint =
        if (y<>0) then (Int (x/y))
                 else  Nil in
    let safediv2 (x:safeint) (y:safeint) : safeint = match y with
        | Int b -> begin
                        match x with
                            | Int a -> (safediv1 a b)
                            | Nil   -> Nil
        | Nil   -> Nil in
    let printsafeint (s:string) (x:safeint) : unit = match x with
        | Int a -> (myprintint s a)
        | Nil   -> (myprintint "Nil" (-1))
    (* Calculate safe integer ((a/b) / (c/d)) *)
    let myfunction (a:int)(b:int)(c:int)(d:int)=
       let x:safeint=safediv1 a b in
       let y:safeint=safediv1 c d in
       let z:safeint=safediv2 x y in
       z in
    let _= printsafeint "Result" (myfunction 256 16 16 4 ) in

From a perspective of usual idioms:

  • Putting all definitions un single top level let is very unusual, and doesn’t help with readability imo.
  • the standard and idiomatic way of representing partial functions is with the option type. So in this case, you’d have safediv : int -> int -> int option.
  • you’re missing t some spaces around =

I would use the option monad.

let ( let* ) = Option.bind

let safediv a b =
  if b = 0 then None
  else Some (a / b)

let double_div a b c d =
  let* ab = safediv a b in
  let* cd = safediv c d in
  safediv ab cd

let myfunction a b c d =
  match double_div a b c d with
  | None -> Printf.printf "Nil\n%!"
  | Some n -> Printf.printf "Int %d\n%!" n

I’m not convinced that your safediv2 makes sense: if you have decided that division is only well-defined on non-failure values, then I think your safediv1 makes it more explicit in its type, and it is good to force the caller to handle failure.