collect
is the F# equivalent of SelectMany however it doesn’t provide all the overloads. Here’s how to make the one you referenced.
let selectMany (ab:'a -> 'b seq) (abc:'a -> 'b -> 'c) input =
input |> Seq.collect (fun a -> ab a |> Seq.map (fun b -> abc a b))
// gives
// val selectMany : ('a -> seq<'b>) -> ('a -> 'b -> 'c) -> seq<'a> -> seq<'c>
I believe F# doesn’t provide all the SelectMany overloads because they would add noise to the library. Here’s all four overloads to SelectMany in Microsoft Naming.
let selectMany (source : 'TSource seq) (selector : 'TSource -> 'TResult seq) =
source |> Seq.collect selector
let selectMany (source : 'TSource seq) (selector : 'TSource -> int -> 'TResult seq) =
source |> Seq.mapi (fun n s -> selector s n) |> Seq.concat
let selectMany (source : 'TSource)
(collectionSelector : 'TSource -> 'TCollection seq)
(resultSelector : 'TSource -> 'TCollection -> 'TResult) =
source
|> Seq.collect (fun sourceItem ->
collectionSelector sourceItem
|> Seq.map (fun collection -> resultSelector sourceItem collection))
let selectMany (source : 'TSource)
(collectionSelector : 'TSource -> int -> 'TCollection seq)
(resultSelector : 'TSource -> 'TCollection -> 'TResult) =
source
|> Seq.mapi (fun n sourceItem ->
collectionSelector sourceItem n
|> Seq.map (fun collection -> resultSelector sourceItem collection))
|> Seq.concat
“F# List operations are more powerful than LINQ…” While seq / list operations are great some real “F# power” comes from Function Composition and Currying.
// function composition
let collect selector = Seq.map selector >> Seq.concat