Skip to content

Exception helper functions #38

@Skyb0rg007

Description

@Skyb0rg007

There are some common patterns for managing exceptions that are syntactic features of many programming languages. Implementing them is possible in Standard ML, but usually requires code duplication. That is why I recommend the following additions to the Fn module:

signature FN = sig
  (* Run the function, returning the exception as a value if execution raised an exception *)
  val try : (unit -> 'a) -> (exn, 'a) Either.either

  (* Run the second thunk after the first, even if an exception was raised *)
  val finally : (unit -> 'a) -> (unit -> unit) -> 'a

  (* Use the provided init and deinit functions to manage the resource 'r,
     making sure to run the deinit function even if an exception is raised.
    Notably: an exception raised in the deinit function will be raised *)
  val bracket : {init : unit -> 'r, deinit : 'r -> unit} -> ('r -> 'a) -> 'a
end

Implementation

fun try th = Either.INR (th ()) handle e => Either.INL e

fun finally f1 f2 = let
      val r = f1 () handle e => (f2 (); raise e)
      in  f2 (); r end

fun bracket {init, deinit} f = let
      val x = init ()
      val r = f x handle e => (deinit x; raise e)
      in  deinit x; r end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions