Thursday, June 10, 2010

F# Tricks: Collecting Some Optional Values

Skip this post if you have no idea what F# is, and think LINQ is stupid.
When you map inputs to outputs with a function that can return None, or Some Output, you get an annoying issue of having a list containing Nones, and Somes. For example:
// Contains both encrypted and un-encrypted files: 
let listOfFiles:Seq

// Return a decrypted File, or None if the file can't be decrypted.
let decryptFile file
 match file with
 | isFileDecryptable file -> Some DecryptFile file
 | _ -> None

// decryptedFiles contains Nones, intertwined with some Some  DecryptedFiles
let decryptedFiles = listOfFiles |> Seq.map decryptFile
Here are two ways to remedy that:
// To get a list of only decrypted files you could do:
let realDecryptedFiles = decryptedFiles |> Seq.filter Option.isSome |> Seq.map Option.get

// However, I prefer the more concise version of: 
let realDecryptedFiles = decryptedFiles |> Seq.collect   Option.toList
If you're an F# guru I'd love to hear your thoughts on this.

No comments: