F# Early Returns - Simple if/else early returns (no monads!)

Date: 2024-01-31 | create | tech | fsharp |

F# is a beautiful language. But a lot of its code looks a little weird - it achieves its beauty by being very particular about the paradigms it supports, often discarding patterns used by mainstream languages that have revealed themselves to be negatives rather than positives.

This can make picking up F# hard.

  • Things look weird.
  • Common patterns don't translate.
  • You code slower.

One of the biggest struggles I had when I got into F# was how to write early returns. Early returns are a common way to make code cleaner in mainstream languages by hoisting invalid conditions to the top of a function, reducing the nesting complexity in the body. But F# is a bit more functional than that and tends to bias towards more expressive techniques like Monads.

But Monads are confusing and I think early returns are still a reasonable pattern in F# so here I'll show you how to do them.

F# Early Returns

We can achieve early returns in F# by relying on the if/then/else conditionals.

  • if - condition
  • then - what to do if true
  • else - continue on

By filling out the then with the early return value you'd like, you can achieve early returns without Monads.

Here's some code:

let earlyReturn 
  (shouldEarly : bool)
  : bool 

  if shouldEarly 
    printfn "Early returning!"

  printfn "Not early returning!"

This code:

  • If it should return early, prints "Early returning!" and returns
  • Else it continues on with the function to print "Not early returning!"

Note that you can chain multiple of these together. In this example we do the same thing but chain two potential early returns with the if/then/else approach.

let earlyReturn2 
  (shouldEarly1 : bool)
  (shouldEarly2 : bool)
  : bool * bool 
  if shouldEarly1 
    printfn "Early return 1"
    (true, false)

  if shouldEarly2
    printfn "Early return 2"
    (false, true) 
  printfn "No early return"
  (false, false)

You can run this code yourself with the FsharpEarlyReturns Replit.


F# is my favorite language but there is a bit of a learning curve to relearn some patterns of doing things. Long-term simple Monads often lend better to composable railroad systems but leaning on if/then/else is a viable option.

If you liked this post you might also like:

Want more like this?

The best / easiest way to support my work is by subscribing for future updates and sharing with your network.