Why is there no Seq.partition in F#

In F# 4.0 (Visual Studio 2015), the core libraries are a lot more uniform than before, but they still do not come with an implementation of Seq.partition. You can find more about this in the F# language design discussion: Regular functional operators producing two or more output collections.

The summary is that the Seq.partition function is quite tricky and a having it could introduce potential performance issues. There a couple of ways it can work:

  • It can iterate over the input collection twice (like the FsSnip version), which can cause issues if you have complex delayed computation (you're doing everything twice)

  • It can iterate over the input once, but then it would have to do some complex mutable state sharing (which could secretly allocate memory).

So, Seq.partition cannot be implemented reasonably while keeping all the good properties that you would expect about the seq<'T> type.


Seq.partition is just a specialized version of Seq.groupBy, so the standard library could implement the former as a wrapper around the latter without introducing any new issues.

let partition predicate source =
    let map =
        source
            |> Seq.groupBy predicate
            |> Map.ofSeq
    let get flag =
        map
            |> Map.tryFind flag
            |> Option.defaultValue Seq.empty
    get true, get false

Tags:

F#