Result vs raise in F# async?

  • A+

It seems like there are two ways to return errors in an async workflow: raise and Result.

let willFailRaise = async {   return raise <| new Exception("oh no!") }  let willFailResult = async {   return Result.Error "oh no!" } 

For the caller, the handling is a bit different:

async {   try      let! x = willFailRaise     // ...   with error ->      System.Console.WriteLine(error) }  async {   let! maybeX = willFailResult   match maybeX with   | Result.Ok x ->      // ...   | Result.Error error ->      System.Console.WriteLine(error) } 

My questions are:

  • What are the advantages / disadvantages of each approach?
  • Which approach is more idiomatic F#?


This is one of the many aspects of F# programming that suffers from the mind-split at the core of the language and its community.

On one hand you have "F# the .NET Framework language" where exceptions are the mechanism for handling errors, on the other - "F# the functional programming language" that borrows its idioms from the Haskell side of the world. This is where Result (also known as Either) comes from.

The answer to the question "which one is idiomatic" will change depending who you ask and what they have seen, but my experience has taught me that when in doubt, you're better off using exceptions. Result type has its uses in moderation, but result-heavy programming style easily gets out of hand, and once that happens it's not a pretty sight.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: