FSharpPlus


Foldable

Data structures that can be folded to a summary value.


Minimal complete definition

static member ToSeq (x:'Foldable<'T>) :seq<'T>

Other operations

FoldMap (x:'Foldable<'T>, f:'T->'Monoid)

Rules

foldMap (f >> g) = foldMap f >> g

Related Abstractions

Concrete implementations

From .Net/F#

From F#+

Suggest another concrete implementation

Examples

#r @"../../src/FSharpPlus/bin/Release/netstandard2.0/FSharpPlus.dll"

open FSharpPlus
open FSharpPlus.Data
open FSharpPlus.Control

let res1_Gt   = foldMap (compare 2) [1;2;3]
let resHelloW = foldMap (fun x -> Some ("hello " + x)) (Some "world")

module FoldableTree =
    type Tree<'a> =
        | Empty 
        | Leaf of 'a 
        | Node of (Tree<'a>) * 'a * (Tree<'a>)

        // add instance for Foldable class
        static member inline FoldMap (t:Tree<_>, f) =
            let rec loop x f =
                match x with
                | Empty          -> zero
                | Leaf  n        -> f n
                | Node (l, k, r) -> loop l f ++ f k ++ loop r f
            loop t f
        static member inline FoldBack (x:Tree<_>, f, z) = FoldBack.FromFoldMap f z x
        static member inline ToSeq    (x:Tree<_>) = Tree<_>.FoldBack (x, (fun x y -> seq {yield x; yield! y}), Seq.empty)
    
    let myTree = Node (Node (Leaf 1, 6, Leaf 3), 2 , Leaf 9)
    let resSum21      = foldMap id   myTree
    let resProduct324 = foldMap Mult myTree
    let res21         = foldBack   (+) myTree 0
    let res21'        = fold       (+) 0 myTree    // <- Tree.Fold is not defined but it fallbacks to the default method (Tree.ToSeq)

module FoldableTree2 =
    type Tree<'a> =
        | Empty 
        | Leaf of 'a 
        | Node of (Tree<'a>) * 'a * (Tree<'a>)

        // add instance for Foldable abstraction (ToSeq is the minimal definition).
        static member ToSeq x =        
            let rec loop t = seq {
                match t with
                | Empty        -> ()
                | Leaf n       -> yield n
                | Node (l,k,r) -> yield k; yield! loop l; yield! loop r}
            loop x
       
        static member inline FoldBack (x, f, z) = 
            let rec _foldMap x f =
                match x with
                | Empty        -> getZero()
                | Leaf n       -> f n
                | Node (l,k,r) -> plus (_foldMap l f) (plus (f k) (_foldMap r f))
            Endo.run (_foldMap x (Endo << f )) z

    
    let tree = Node (Node (Leaf 1, 6, Leaf 3), 2 , Leaf 9)
    let res21  = foldBack   (+) tree 0

    // Following operations work by falling back to Tree.ToSeq which is the default
    let res21' = fold   (+) 0   tree      
    let resTr  = exists ((=) 3) tree
    let resS3  = tryPick (fun x -> if x = 3 then Some x else None) tree
Multiple items
val seq: sequence: seq<'T> -> seq<'T>

--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
namespace FSharpPlus
namespace FSharpPlus.Data
namespace FSharpPlus.Control
val res1_Gt: int
val foldMap: f: ('T -> 'Monoid) -> x: 'Foldable<'T> -> 'Monoid (requires member FoldMap)
<summary> Folds by mapping all values to a Monoid </summary>
<category index="11">Foldable</category>
val compare: e1: 'T -> e2: 'T -> int (requires comparison)
val resHelloW: string option
val x: string
union case Option.Some: Value: 'T -> Option<'T>
'a
Multiple items
union case Tree.Empty: Tree<'a>

--------------------
type Empty = inherit Default1 static member Empty: _output: seq<'T> * _mthd: Default2 -> seq<'T> + 7 overloads static member Invoke: unit -> 'Alternative<'T> (requires member Empty) static member InvokeOnInstance: unit -> 'Alternative<'T> (requires member Empty)
union case Tree.Leaf: 'a -> Tree<'a>
union case Tree.Node: Tree<'a> * 'a * Tree<'a> -> Tree<'a>
type Tree<'a> = | Empty | Leaf of 'a | Node of Tree<'a> * 'a * Tree<'a> static member FoldBack: x: Tree<'a0> * f: ('a0 -> 'b -> 'b) * z: 'b -> 'b static member FoldMap: t: Tree<'a0> * f: ('a0 -> 'b) -> 'b (requires member ``+`` and member Zero) static member ToSeq: x: Tree<'a0> -> seq<'a0>
type FoldMap = inherit Default1 static member FoldMap: x: 'a0 option * f: ('a0 -> 'a1) * _impl: FoldMap -> 'a1 (requires member Zero) + 6 overloads static member FromFoldFoldBack: f: ('a0 -> 'a1) -> x: 'a2 -> 'a1 (requires member ``+`` and member Zero and member FoldBack) static member Invoke: f: ('T -> 'Monoid) -> x: 'Foldable'<T> -> 'Monoid (requires member FoldMap)
val t: Tree<'a>
val f: ('a -> 'b) (requires member ``+`` and member Zero)
val loop: x: Tree<'a> -> f: ('a -> 'b) -> 'b (requires member ``+`` and member Zero)
val x: Tree<'a>
val zero<'Monoid (requires member Zero)> : 'Monoid (requires member Zero)
<summary> A value that represents the 0 element of a Monoid. </summary>
<category index="4">Monoid</category>
val n: 'a
val l: Tree<'a>
val k: 'a
val r: Tree<'a>
type FoldBack = inherit Default1 static member FoldBack: x: 'F * f: ('a -> 'b -> 'b) * z: 'b * _impl: Default2 -> 'b (requires member ToList and 'F :> ResizeArray<'a>) + 10 overloads static member FromFoldMap: f: ('c -> 't -> 't) -> z: 't -> x: 'd -> 't (requires member FoldMap) static member Invoke: folder: ('T -> 'State -> 'State) -> state: 'State -> foldable: 'Foldable'<T> -> 'State (requires member FoldBack)
val f: ('a -> 'b -> 'b)
val z: 'b
static member FoldBack.FromFoldMap: f: ('c -> 't -> 't) -> z: 't -> x: 'd -> 't (requires member FoldMap)
type ToSeq = inherit Default1 static member Invoke: source: 'Foldable<'T> -> seq<'T> (requires member ToSeq) static member InvokeOnInstance: source: 'Foldable<'T> -> seq<'T> (requires member ToSeq) static member ToSeq: x: seq<'T> * _impl: ToSeq -> seq<'T> + 7 overloads
val x: 'a
val y: seq<'a>
Multiple items
module Seq from FSharpPlus.Data
<summary> Additional operations on Seq </summary>

--------------------
module Seq from FSharpPlus.Operators

--------------------
module Seq from FSharpPlus
<summary> Additional operations on Seq </summary>

--------------------
module Seq from Microsoft.FSharp.Collections
val empty<'T> : seq<'T>
val myTree: Tree<int>
val resSum21: int
val id: x: 'T -> 'T
val resProduct324: Mult<int>
Multiple items
union case Mult.Mult: 'a -> Mult<'a>

--------------------
[<Struct>] type Mult<'a> = | Mult of 'a static member (+) : Mult<'n> * Mult<'n> -> Mult<'a2> (requires member ( * )) static member Zero: unit -> Mult<'a1> (requires member One)
<summary> Numeric wrapper for multiplication monoid (*, 1) </summary>
val res21: int
val foldBack: folder: ('T -> 'State -> 'State) -> foldable: 'Foldable<'T> -> state: 'State -> 'State (requires member FoldBack)
<summary> Foldable &lt;summary&gt;Applies a function to each element of the foldable, starting from the end, threading an accumulator argument through the computation. If the input function is &lt;c&gt;f&lt;/c&gt; and the elements are &lt;c&gt;i0...iN&lt;/c&gt; then computes &lt;c&gt;f i0 (...(f iN s))&lt;/c&gt;.&lt;/summary&gt; &lt;category index="11"&gt;Foldable&lt;/category&gt; &lt;param name="folder"&gt;The function to update the state given the input elements.&lt;/param&gt; &lt;param name="foldable"&gt;The input foldable.&lt;/param&gt; &lt;param name="state"&gt;The initial state.&lt;/param&gt; &lt;returns&gt;The state object after the folding function is applied to each element of the foldable.&lt;/returns&gt; </summary>
val res21': int
val fold: folder: ('State -> 'T -> 'State) -> state: 'State -> foldable: 'Foldable<'T> -> 'State (requires member Fold)
<summary>Applies a function to each element of the foldable, threading an accumulator argument through the computation. Take the second argument, and apply the function to it and the first element of the foldable. Then feed this result into the function along with the second element and so on. Return the final result. If the input function is <c>f</c> and the elements are <c>i0...iN</c> then computes <c>f (... (f s i0) i1 ...) iN</c>.</summary>
<category index="11">Foldable</category>
<param name="folder">The function to update the state given the input elements.</param>
<param name="state">The initial state.</param>
<param name="foldable">The input foldable.</param>
<returns>The final state value.</returns>
type Tree<'a> = | Empty | Leaf of 'a | Node of Tree<'a> * 'a * Tree<'a> static member FoldBack: x: Tree<'a0> * f: ('a0 -> 'b -> 'b) * z: 'b -> 'b static member ToSeq: x: Tree<'a0> -> seq<'a0>
val loop: t: Tree<'a> -> seq<'a>
val _foldMap: x: Tree<'a> -> f: ('a -> Endo<'b>) -> Endo<'b>
val f: ('a -> Endo<'b>)
val getZero: unit -> 'Monoid (requires member Zero)
<summary> Gets a value that represents the 0 element of a Monoid. </summary>
<category index="4">Monoid</category>
val plus: x: 'Monoid -> y: 'Monoid -> 'Monoid (requires member ``+``)
<summary> Combines two monoids in one. </summary>
<category index="4">Monoid</category>
Multiple items
union case Endo.Endo: ('t -> 't) -> Endo<'t>

--------------------
module Endo from FSharpPlus.Data
<summary> Basic operations on Endo </summary>

--------------------
[<Struct>] type Endo<'t> = | Endo of ('t -> 't) static member (+) : Endo<'T> * Endo<'T> -> Endo<'T> static member Zero: unit -> Endo<'T>
<summary> The monoid of endomorphisms under composition. </summary>
val run: Endo<'T> -> ('T -> 'T)
val tree: Tree<int>
val resTr: bool
val exists: predicate: ('T -> bool) -> source: 'Foldable<'T> -> bool (requires member Exists)
<summary>Tests if any element of the list satisfies the given predicate.</summary>
<category index="11">Foldable</category>
<remarks>The predicate is applied to the elements of the input foldable. If any application returns true then the overall result is true and no further elements are tested. Otherwise, false is returned.</remarks>
<param name="predicate">The function to test the input elements.</param>
<param name="source">The input foldable.</param>
<returns>True if any element satisfies the predicate.</returns>
val resS3: int option
val tryPick: chooser: ('T -> 'U option) -> source: 'Foldable<'T> -> 'U option (requires member TryPick)
<summary>Applies the given function to successive elements, returning <c>Some(x)</c> the first result where function returns <c>Some(x)</c> for some x. If no such element exists then return <c>None</c>.</summary>
<category index="11">Foldable</category>
<param name="chooser">The function to generate options from the elements.</param>
<param name="source">The input foldable.</param>
<returns>The first resulting value or None.</returns>
val x: int
union case Option.None: Option<'T>