Errors in Standard ML

In Standard ML, error handling is typically done using the option type or by raising exceptions. We’ll use a combination of both to demonstrate error handling concepts similar to those in the original example.

(* In Standard ML, we use exceptions for error handling *)
exception CantWorkWith42 of string
exception OutOfTea of string
exception PowerFailure of string

(* This function demonstrates basic error handling *)
fun f arg = 
    if arg = 42 then
        NONE (* Similar to returning an error *)
    else
        SOME (arg + 3) (* Success case *)

(* This function demonstrates using exceptions *)
fun makeTea arg =
    case arg of
        2 => raise OutOfTea "no more tea available"
      | 4 => raise PowerFailure "can't boil water"
      | _ => () (* Success case *)

(* Main function to demonstrate error handling *)
fun main () =
    let
        (* Demonstrating f function *)
        val _ = 
            List.app
                (fn i =>
                    case f i of
                        SOME r => print ("f worked: " ^ Int.toString r ^ "\n")
                      | NONE => print ("f failed: can't work with 42\n"))
                [7, 42]

        (* Demonstrating makeTea function *)
        val _ =
            List.app
                (fn i =>
                    ((makeTea i; print "Tea is ready!\n")
                    handle
                        OutOfTea msg => print ("We should buy new tea! " ^ msg ^ "\n")
                      | PowerFailure msg => print ("Now it is dark. " ^ msg ^ "\n")
                      | _ => print "Unknown error occurred\n"))
                [0, 1, 2, 3, 4]
    in
        ()
    end

(* Run the main function *)
val _ = main ()

In Standard ML, we use a combination of the option type and exceptions to handle errors:

  1. The f function returns an option type, where NONE represents an error and SOME represents success.

  2. We define custom exceptions CantWorkWith42, OutOfTea, and PowerFailure to represent specific error conditions.

  3. The makeTea function raises exceptions instead of returning error values.

  4. In the main function, we use pattern matching to handle the option return type of f, and we use exception handling to catch and process errors from makeTea.

  5. The List.app function is used to iterate over lists, similar to the for loops in the original example.

To run this program, save it to a file (e.g., errors.sml) and use your Standard ML interpreter. For example, with MLton:

$ mlton errors.sml
$ ./errors
f worked: 10
f failed: can't work with 42
Tea is ready!
Tea is ready!
We should buy new tea! no more tea available
Tea is ready!
Now it is dark. can't boil water

This example demonstrates error handling in Standard ML using both the option type and exceptions, which are idiomatic ways to handle errors in this language.