United Kingdom: +44 (0)208 088 8978

Yielding Options in List Comprehension Expressions

In F#, you have a couple options for even something as simple as yielding an option into a list. Let's compare them!

We're hiring Software Developers

Click here to find out more

In Elmish apps, we often find ourselves in situations where the element to be displayed to the user is determined by processing a list of option values. In such cases, often the elements that are stored in Some option members are rendered on the screen whereas the members with the None value are discarded. Think of buttons and other UI elements, or even the pages themselves.

In this short blogpost, I will show you a couple of very simple ways to yield an option value inside a list and explain what is involved as well as how the two approaches compare.

An Option Value

For demonstration purposes, I will create an option of string.

let maybeAValue = Some "Test"

Pattern Matching

One way we often see option types being unwrapped in a list comprehension expression looks like this:

let firstVersion = [
    "Hello"
    "There"
    match maybeAValue with
    | Some v -> v
    | None -> ()
]

As you can see, the firstVersion list has two string literal members that read "Hello" and "There". Its third member in this case is going to be "Test" since Some "Test" is what we've bound to the maybeAValue identifier. The way that we determine the value of the third member is to perform a pattern match on the maybeAValue identifier and return its value if it's a Some. If it's a None, unit is returned and the list only has two members.

Also, note that in this case, all the other members of the list except the last one fits into a single whereas the we break the pattern match for the last member into three lines.

Option.toList and yield!

Now, let's look at an alternative approach that uses the Option.toList method and the yield! keyword that makes things a little more concise.

let secondVersion = [
    "Hello"
    "There"
    yield! maybeAValue |> Option.toList
]

Compare this snippet of code to the one before. As you can see, what was previously achieved in three lines is now achieved in a single line. What enables us to do this is the yield! keyword and the toList method of the Option module. When the third line inside the list comprehension expression is run, the string option will be passed into the Option.toList method. This method will return a list containing the value inside the maybeAValue if it's a Some, and an empty list if it's a None.

What yield! does is to simple take the members of an inner sequence and insert them into the outer sequence. In our specific case, the inner sequence is a list with a single member – "Test". And so in the final analysis, the secondVersion list will contain three members: "Hello", "There" and "Test". However, if we've assigned None to the maybeAValue identifier, we would again have a list with only the initial two members at the end.

Summary

I am of the opinion that even if the case is as simple as what we've looked at here, we should go with the simpler, more concise option to improve the readability of the bigger picture and keep things tidier. The fact that in the second approach we don't lose much of the readability even if we write all of the code for yielding the option into a single line makes it much more preferable to use for me. What do you think? Now that you are aware of both of these approaches, which one would you pick when you need to yield an option into a list the next time around?