Latest Blog Posts

This post is Part 3 of a series on type-safe failure handling.
Part 1 is in Scala and examines Scala’s Either class as a mechanism for early-return control flow.
Part 2 ports the program to Haskell, where I/O is explicitly encapsulated by the IO type.
This post will demonstrate the use of monad transformers to refactor the example from Part 2.

In a previous post, we added exception handling to a hypothetical API server written in Scala. Since Scala implicitly allows arbitrary I/O anywhere, modeling exception handling by adding a layer of indirection using Either values was essentially free. I wanted to try implementing the same logic in Haskell, which would force us to deal with intermingling exception handling intermingled with explicit I/O, creating two layers of abstraction that we’ll have to juggle.

A hotshot teammate just pulled a miracle. Over the weekend, they built the API our customers have been promised for the past year, averting an existential crisis for the company. One problem: Only the happy path returns a response; all exceptional circumstances simply crash the computer. So, it’s up to us to productionalize the prototype by adding appropriate error handling, and we won’t sacrifice compile-time safety and re-usability along the way.

Scala’s Try class is broken.
Not “broken” in the sense that it doesn’t fulfill its purpose: its purpose is to sandbox Throwables in an algebraic sum construct and provide a monadic interface over the sandbox.
It does that just fine.
Try is broken in the sense that one of its methods, _.toOption can return malformed Option values, violating our trust in the semantics of the Option class and leading to potential instability down the call stack.