open System.Text type Folder<'State> = abstract Invoke<'T> : 'State * 'T -> 'State type FoldStep<'State> = 'State -> 'State type FoldBuilder<'Folder, 'State when 'Folder :> Folder<'State>>() = member this.Zero(): FoldStep<'State> = id member inline this.Combine( [] f: FoldStep<'State>, [] g: FoldStep<'State>) : FoldStep<'State> = fun state -> g (f state) member inline this.Delay([] f: unit -> FoldStep<'State>) = f() member inline this.Yield(value: 'T): FoldStep<'State> = fun state -> Unchecked.defaultof<'Folder>.Invoke(state, value) [] type StringBuilderFolder = interface Folder with member _.Invoke(state: StringBuilder, value: 'T) = state.Append(value) let inline fold<'Folder, 'State when 'Folder :> Folder<'State>> = FoldBuilder<'Folder, 'State>() let f = (fold { 1; "lol"; 42; 'a'; 5.1 }) (StringBuilder()) printfn "%s" (f.ToString())