FSharpPlus


Extensions

Extensions are what you probably expect: helper functions for existing types.

They are defined as modules with the same name as the types they operate on under the FSharpPlus namespace, so can be accessed via:

open FSharpPlus

Some functions are common across foldable types such as intercalate on List, Array and Seq, and others are common across wrapping containers, such as map, bind and apply on List, Array, and Seq, but also Option and Result.

Construction:

The singleton function is already defined for Seq, Array and List, but F#+ adds it for Enumerator:

To construct MonadError instances (Result or Choice) you can use result/throw:

It's also possible to construct by wrapping exception producing functions:

// throws "ArgumentException: The input sequence was empty."
let expectedSingleItem1 : int = List.exactlyOne []

// returns a Result.Error holding the exception as its value:
let expectedSingleItem2 : Result<int,exn> = Result.protect List.exactlyOne []

// ...or like typical try prefixed functions, treat exception as None
let expectedSingleItem3 : Option<int> = Option.protect List.exactlyOne []

// which might look like this:
let inline tryExactlyOne xs = Option.protect List.exactlyOne xs

Deconstruction (unwrapping):

Some extensions on Result are designed to behave like Option:

To deconstruct MonadError instances (Result or Choice) use:

Note that there is also the generic either operator function that works exactly the same as Result.either.

Also, see the generic function option that unwraps an Option in a similar way to either.

On Foldables

Foldables are the class of data structures that can be folded to a summary value. Most collections, or specifically 'foldable' instances implement these:

let a = ["Bob"; "Jane"] |> List.intersperse "and"
// vat a : string list = ["Bob"; "and"; "Jane"]

let b = "WooHoo" |> String.intersperse '-'
// val b : string = "W-o-o-H-o-o"
let c = [[1;2]; [3;4]] |> List.intercalate [-1;-2];;
// val c : int list = [1; 2; -1; -2; 3; 4]

let d = ["Woo"; "Hoo"] |> String.intercalate "--o.o--";;
// val d : string = "Woo--o.o--Hoo"

On Monad/Functor/Applicatives

Types that implement these will (typically) have these functions defined:

These can also be invoked from the generic functions without module prefix as per generic functions & operators.

Flatten:

Flatten can be used when a container has another container inside it:

Note that on traversable types like List, Array and Seq, FSharp Core uses the more common concat for flatten and so this naming is continued for Enumerable:

Partitioning:

Partitioning can be done by applying a separating function that produces a Choice:

let isEven x = (x % 2) = 0
let chooseEven x = if isEven x then Choice1Of2 x else Choice2Of2 x

let e = [1; 2; 3; 4] |> List.partitionMap chooseEven
// val e : int list * int list = ([2; 4], [1; 3])

Conversion functions:

F#+ adds functions to convert between Result, Choice and Option types.

These should be self explanatory, but be aware that sometimes they are 'lossy' usually when converting to Option:

// Convert a Result to an Option - effectively throws away error value // when present, by replacing with None

request |> validateRequest |> Option.ofResult

Going the other way is similar, but a value needs to be filled in for None:

let xs = ["some value"]
let firstElementOption = xs |> List.tryHead

// Convert an `Option` to a `Result` will use unit as the Error:
firstElementOption |> Option.toResult

// ...but you can specify an error value with Option.toResultWith:
firstElementOption |> Option.toResultWith "No Element"

Converting between Choice and Result is often useful:

let asyncChoice = anAsyncValue |> Async.Catch |> Async.map Result.ofChoice

The String type:

Collections / Traversable types:

Async and Tasks:

Option, Choice and Result types:

Extensions Methods (on existing types):

These are usable from C#

namespace FSharpPlus
val expectedSingleItem1: int
Multiple items
val int: value: 'T -> int (requires member op_Explicit)
<summary>Converts the argument to signed 32-bit integer. This is a direct conversion for all primitive numeric types. For strings, the input is converted using <c>Int32.Parse()</c> with InvariantCulture settings. Otherwise the operation requires an appropriate static conversion method on the input type.</summary>
<param name="value">The input value.</param>
<returns>The converted int</returns>
<example id="int-example"><code lang="fsharp"></code></example>


--------------------
[<Struct>] type int = int32
<summary>An abbreviation for the CLI type <see cref="T:System.Int32" />.</summary>
<category>Basic Types</category>


--------------------
type int<'Measure> = int
<summary>The type of 32-bit signed integer numbers, annotated with a unit of measure. The unit of measure is erased in compiled code and when values of this type are analyzed using reflection. The type is representationally equivalent to <see cref="T:System.Int32" />.</summary>
<category>Basic Types with Units of Measure</category>
Multiple items
module List from FSharpPlus
<summary> Additional operations on List </summary>

--------------------
module List from Microsoft.FSharp.Collections
<summary>Contains operations for working with values of type <see cref="T:Microsoft.FSharp.Collections.list`1" />.</summary>
<namespacedoc><summary>Operations for collections such as lists, arrays, sets, maps and sequences. See also <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/fsharp-collection-types">F# Collection Types</a> in the F# Language Guide. </summary></namespacedoc>


--------------------
type List<'T> = | op_Nil | op_ColonColon of Head: 'T * Tail: 'T list interface IReadOnlyList<'T> interface IReadOnlyCollection<'T> interface IEnumerable interface IEnumerable<'T> member GetReverseIndex: rank: int * offset: int -> int member GetSlice: startIndex: int option * endIndex: int option -> 'T list static member Cons: head: 'T * tail: 'T list -> 'T list member Head: 'T member IsEmpty: bool member Item: index: int -> 'T with get ...
<summary>The type of immutable singly-linked lists.</summary>
<remarks>Use the constructors <c>[]</c> and <c>::</c> (infix) to create values of this type, or the notation <c>[1;2;3]</c>. Use the values in the <c>List</c> module to manipulate values of this type, or pattern match against the values directly. </remarks>
<exclude />
val exactlyOne: list: 'T list -> 'T
<summary>Returns the only element of the list.</summary>
<param name="list">The input list.</param>
<returns>The only element of the list.</returns>
<exception cref="T:System.ArgumentException">Thrown when the input does not have precisely one element.</exception>
<example id="exactlyOne-1"><code lang="fsharp"> ["the chosen one"] |&gt; List.exactlyOne // evaluates "the chosen one" </code></example>
<example id="exactlyOne-2"><code lang="fsharp"> let input : string list = [] input |&gt; List.exactlyOne </code> Will throw the exception: <c>System.ArgumentException: The input sequence was empty</c></example>
<example id="exactlyOne-3"><code lang="fsharp"> [1..5] |&gt; List.exactlyOne </code> Will throw the exception: <c>System.ArgumentException: The input sequence contains more than one element</c></example>
val expectedSingleItem2: Result<int,exn>
Multiple items
module Result from FSharpPlus
<summary> Additional operations on Result&lt;'T,'Error&gt; </summary>

--------------------
module Result from Microsoft.FSharp.Core
<summary>Contains operations for working with values of type <see cref="T:Microsoft.FSharp.Core.FSharpResult`2" />.</summary>
<category>Choices and Results</category>


--------------------
[<Struct>] type Result<'T,'TError> = | Ok of ResultValue: 'T | Error of ErrorValue: 'TError
<summary>Helper type for error handling without exceptions.</summary>
<category>Choices and Results</category>
type exn = System.Exception
<summary>An abbreviation for the CLI type <see cref="T:System.Exception" />.</summary>
<category>Basic Types</category>
val protect: f: ('T -> 'U) -> x: 'T -> Result<'U,exn>
<summary> Creates a safe version of the supplied function, which returns a Result&lt;'U,exn&gt; instead of throwing exceptions. </summary>
val expectedSingleItem3: Option<int>
Multiple items
module Option from FSharpPlus
<summary> Additional operations on Option </summary>

--------------------
module Option from Microsoft.FSharp.Core
<summary>Contains operations for working with options.</summary>
<category>Options</category>
val protect: f: ('T -> 'U) -> x: 'T -> 'U option
<summary> Creates a safe version of the supplied function, which returns an option&lt;'U&gt; instead of throwing exceptions. </summary>
val tryExactlyOne: xs: 'a list -> 'a option
val xs: 'a list
val a: string list
val intersperse: separator: 'T -> source: 'T list -> 'T list
<summary> Inserts a separator element between each element in the source list. </summary>
val b: string
Multiple items
module String from FSharpPlus
<summary> Additional operations on String </summary>

--------------------
module String from Microsoft.FSharp.Core
<summary>Functional programming operators for string processing. Further string operations are available via the member functions on strings and other functionality in <a href="http://msdn2.microsoft.com/en-us/library/system.string.aspx">System.String</a> and <a href="http://msdn2.microsoft.com/library/system.text.regularexpressions.aspx">System.Text.RegularExpressions</a> types. </summary>
<category>Strings and Text</category>
val intersperse: element: char -> source: string -> string
<summary> Inserts a separator char between each char in the source string. </summary>
val c: int list
val intercalate: separator: 'T list -> source: seq<'T list> -> 'T list
<summary> Concatenates all elements, using the specified separator between each element. </summary>
val d: string
val intercalate: separator: string -> source: seq<string> -> string
<summary> Concatenates all elements, using the specified separator between each element. </summary>
val isEven: x: int -> bool
val x: int
val chooseEven: x: int -> Choice<int,int>
union case Choice.Choice1Of2: 'T1 -> Choice<'T1,'T2>
<summary>Choice 1 of 2 choices</summary>
union case Choice.Choice2Of2: 'T2 -> Choice<'T1,'T2>
<summary>Choice 2 of 2 choices</summary>
val e: int list * int list
val partitionMap: mapping: ('T -> Choice<'T1,'T2>) -> source: 'T list -> 'T1 list * 'T2 list
<summary> Creates two lists by applying the mapping function to each element in the list and classifying the transformed values depending on whether they were wrapped with Choice1Of2 or Choice2Of2. </summary>
<returns> A tuple with both resulting lists. </returns>
val xs: string list
val firstElementOption: string option
val tryHead: list: 'T list -> 'T option
<summary>Returns the first element of the list, or <c>None</c> if the list is empty.</summary>
<param name="list">The input list.</param>
<returns>The first element of the list or None.</returns>
<example id="try-head-1"><code lang="fsharp"> let inputs = [ "banana"; "pear" ] inputs |&gt; List.tryHead </code> Evaluates to <c>Some "banana"</c></example>
<example id="try-head-2"><code lang="fsharp"> let inputs : int list = [] inputs |&gt; List.tryHead </code> Evaluates to <c>None</c></example>
val toResult: source: 'T option -> Result<'T,unit>
<summary>Converts an option to a Result.</summary>
<param name="source">The option value.</param>
<returns>The resulting Result value.</returns>
val toResultWith: errorValue: 'Error -> source: 'T option -> Result<'T,'Error>
<summary>Converts an option to a Result.</summary>
<param name="errorValue">The error value to be used in case of None.</param>
<param name="source">The option value.</param>
<returns>The resulting Result value.</returns>