Exercises in Programming Style–The One

Check out my new course Learn you some Lambda best practice for great good! and learn the best practices for performance, cost, security, resilience, observability and scalability.

NOTE : read the rest of the series, or check out the source code.

If you enjoy read­ing these exer­cises then please buy Crista’s book to sup­port her work.


Fol­low­ing on from the last post, we will look at The One style today.


Style 9 – The One

You may also know this style as Monads, which many consider to be a scary word… That said, I know a few smart people who have done excellent talks to explain Monads in a way that’s easy to understand, check out these links:

and this post is probably the best of the lot, especially if you enjoy cartoon drawings!



  • Existence of an abstraction to which values can be converted
  • This abstraction provides operations to:
    1. wrap around values, so that they become the abstraction
    2. bind itself to functions, so to establish sequences of functions
    3. unwrap the value, to examine the final result
  • Larger problem is solved as a pipeline of functions bound together, with unwrapping happening at the end
  • Particularly for The One style, the bind operation simply calls the given function, giving it the value that it holds, and holds on to the returned value


Version 1 (simple bind)

In terms of a port from Crista’s example, most of code is very similar to the Pipeline style, except their return values have to be wrapped into another abstraction.

I thought about this and couldn’t come up with a really meaningful abstraction, so I settled on a single-case Result type:


Next, we need to define the ‘bind’ operator (which, the convention is to use >>=):


the rest is pretty straight forward (i.e. copy from Pipeline style, add |> Result to end of each function):


Before we move on though, I wanna bring your attention to the removeStopWords function briefly:


If you recall, readFile now returns a Result<string> so in order to split the wrapped string we’ll need to unbox it first. Since our Result type is single-cased, we can kinda cheat by using pattern matching to extract the wrapped string value out and bind it to the raw value:



Now, we want to chain the functions together using our bind:


Oh no! What’s happening here?!?

Ah, the compiler is telling us that ‘bind’ is expecting a continuation that returns a value wrapped in the Result type but printMe returns unit instead.

That’s a bummer, so we can either rewrite printMe to be compliant of such requirement. Or, we can use another concept that’s commonly used as a ‘lift’:


A lift is simply a function that takes a function that returns an unwrapped value, and returns a modified version that returns a wrapped value instead.


So with a tiny change, we can make everything work now:image


But but but, this is F#, and we have computation expressions, so we can do better than that!

(if you’re totally new to the idea of computation expressions, then I recommend reading at least the first few posts in Scott’s excellent series before proceeding)


Version 2 (computation expressions)

Have you read Scott’s introductory posts on computation expressions? Have a basic understanding of how they work?

Good, then let’s continue.


Here is a very simple CE that works with the Result type:


and now we can use it to refactor the removeStopWords function:


Here, return! is translated to the ReturnFrom method in TheOneBuilder and unwraps the Result<string> for us so we don’t need to manually unwrap it with pattern matching.


To chain the functions together, we no longer have to use bind and can instead let the CE deal with unwrapping values for us:


Also, notice that we no longer have to ‘lift’ the printMe function.

aside : you might also noticed that I’m shadowing previous instances of text, words and wordFreqs as I go. It’s not necessary, and many people would have preferred text’, text’’, etc. instead.

I think in this particular case shadowing actually helps me prevent the accidental misuse of discarded values. E.g. the following would be a bug (and I’ve made this type of mistakes in the past..)

theOne {

    let! text = readFile ”p & p”

    let! text’ = filterChars text

    let! text’’ = normalize text  // should be text’ instead



That said, I personally think >>= is still a very useful combinator, and would prefer to write the above as:



You can find the source code for this exer­cise here (v1) and here (v2).

Liked this article? Support me on Patreon and get direct help from me via a private Slack channel or 1-2-1 mentoring.
Subscribe to my newsletter

Hi, I’m Yan. I’m an AWS Serverless Hero and the author of Production-Ready Serverless.

I specialise in rapidly transitioning teams to serverless and building production-ready services on AWS.

Are you struggling with serverless or need guidance on best practices? Do you want someone to review your architecture and help you avoid costly mistakes down the line? Whatever the case, I’m here to help.

Hire me.

Check out my new podcast Real-World Serverless where I talk with engineers who are building amazing things with serverless technologies and discuss the real-world use cases and challenges they face. If you’re interested in what people are actually doing with serverless and what it’s really like to be working with serverless day-to-day, then this is the podcast for you.

Check out my new course, Learn you some Lambda best practice for great good! In this course, you will learn best practices for working with AWS Lambda in terms of performance, cost, security, scalability, resilience and observability. We will also cover latest features from re:Invent 2019 such as Provisioned Concurrency and Lambda Destinations. Enrol now and start learning!

Check out my video course, Complete Guide to AWS Step Functions. In this course, we’ll cover everything you need to know to use AWS Step Functions service effectively. There is something for everyone from beginners to more advanced users looking for design patterns and best practices. Enrol now and start learning!

Are you working with Serverless and looking for expert training to level-up your skills? Or are you looking for a solid foundation to start from? Look no further, register for my Production-Ready Serverless workshop to learn how to build production-grade Serverless applications!

Find a workshop near you