Exercises in Programming Style–The One

Yan Cui

I help clients go faster for less using serverless technologies.

This article is brought to you by

Is your CI build step taking too long? Try Depot for free today and experience up to 40x faster build speed!

Unlock faster CI for FREE

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).

Whenever you’re ready, here are 4 ways I can help you:

  1. Production-Ready Serverless: Join 20+ AWS Heroes & Community Builders and 1000+ other students in levelling up your serverless game. This is your one-stop shop for quickly levelling up your serverless skills.
  2. Do you want to know how to test serverless architectures with a fast dev & test loop? Check out my latest course, Testing Serverless Architectures and learn the smart way to test serverless.
  3. I help clients launch product ideas, improve their development processes and upskill their teams. If you’d like to work together, then let’s get in touch.
  4. Join my community on Discord, ask questions, and join the discussion on all things AWS and Serverless.

Leave a Comment

Your email address will not be published. Required fields are marked *