Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Functional Transformation of a collection of Option<T>

I have a collection of Option<T> instances and want to transform from IEnumerable<Option<T>> to Option<IEnumerable<T>>

If ALL the options have a value, then I want a Some<IEnumerable<T>> with the collected values, if ANY of the items in the collection are None, then I want a None<IEnumerable<T>>

This seems like it would be quite a common functional transformation, but i'm not sure if it exists in mainstream functional libraries, or what it would be called. Seems similar to FlatMap, but not quite, as I don't want to just filter out the None values.

I could implement it myself, but would like to find out if it exists already as a functional construct. Don't mind what language, C#, Scala, Haskell etc.

like image 259
Martin Cooper Avatar asked Sep 16 '25 07:09

Martin Cooper


2 Answers

Language-ext author here, you simply need to call .Sequence() to reverse the inner and outer monads:

IEnumerable<Option<int>> items = ...;

Option<IEnumerable<int>> result = items.Sequence();

It has the exact behaviour you're looking for of returning None if any item in the sequence is None, and Some otherwise.

You can also use .Traverse(...) to map the results as you go.

like image 79
louthster Avatar answered Sep 18 '25 20:09

louthster


There's more than one 'language family' of functional programming concepts.

In Haskell (and, apparently, Scala) this is called sequence and is part of an abstraction or type class called Traversable; sequence is a special case of a traversal.

Other language famiilies exist, most notably ML. This is the where the term Option comes from (which in Haskell is called Maybe). While I'm well-versed in F# (which is one ML dialect), I'm not aware that traverse/sequence has an established terminology there.

like image 21
Mark Seemann Avatar answered Sep 18 '25 21:09

Mark Seemann