5 people like it.

Recursor

A sugar around IEnumerator<'a> to make it nicer to use with recursive functions

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
module Recursor

type Recursor<'a> (enumerable:System.Collections.Generic.IEnumerable<'a>) =
    let enumerator = enumerable.GetEnumerator ()

    let mutable moreData = enumerator.MoveNext ()

    member __.TryGetValue ([<System.Runtime.InteropServices.OutAttribute>] out:byref<'a>) =
        if moreData then
            out <- enumerator.Current
            true
        else
            false

    member this.Next =
        moreData <- enumerator.MoveNext ()
        this

type System.Collections.Generic.IEnumerable<'a> with
    member this.Recursor = Recursor this
    
// example
let inline sum (e:System.Collections.Generic.IEnumerable<int>) =
    let rec f (cursor:Recursor<int>) total =
        match cursor.TryGetValue () with
        | false, _-> total
        | true, value -> f cursor.Next (total+value)

    f e.Recursor 0
module Recursor
Multiple items
type Recursor<'a> =
  new : enumerable:IEnumerable<'a> -> Recursor<'a>
  member TryGetValue : out:byref<'a> -> bool
  member Next : Recursor<'a>

Full name: Recursor.Recursor<_>

--------------------
new : enumerable:System.Collections.Generic.IEnumerable<'a> -> Recursor<'a>
val enumerable : System.Collections.Generic.IEnumerable<'a>
namespace System
namespace System.Collections
namespace System.Collections.Generic
type IEnumerable<'T> =
  member GetEnumerator : unit -> IEnumerator<'T>

Full name: System.Collections.Generic.IEnumerable<_>
val enumerator : System.Collections.Generic.IEnumerator<'a>
System.Collections.Generic.IEnumerable.GetEnumerator() : System.Collections.Generic.IEnumerator<'a>
val mutable moreData : bool
System.Collections.IEnumerator.MoveNext() : bool
member Recursor.TryGetValue : out:byref<'a> -> bool

Full name: Recursor.Recursor`1.TryGetValue
namespace System.Runtime
namespace System.Runtime.InteropServices
Multiple items
type OutAttribute =
  inherit Attribute
  new : unit -> OutAttribute

Full name: System.Runtime.InteropServices.OutAttribute

--------------------
System.Runtime.InteropServices.OutAttribute() : unit
val out : byref<'a>
type byref<'T> = (# "<Common IL Type Omitted>" #)

Full name: Microsoft.FSharp.Core.byref<_>
property System.Collections.Generic.IEnumerator.Current: 'a
val this : Recursor<'a>
member Recursor.Next : Recursor<'a>

Full name: Recursor.Recursor`1.Next
val this : System.Collections.Generic.IEnumerable<'T>
Multiple items
member System.Collections.Generic.IEnumerable.Recursor : Recursor<'T>

Full name: Recursor.Recursor

--------------------
type Recursor<'a> =
  new : enumerable:IEnumerable<'a> -> Recursor<'a>
  member TryGetValue : out:byref<'a> -> bool
  member Next : Recursor<'a>

Full name: Recursor.Recursor<_>

--------------------
new : enumerable:System.Collections.Generic.IEnumerable<'a> -> Recursor<'a>
val sum : e:System.Collections.Generic.IEnumerable<int> -> int

Full name: Recursor.sum
val e : System.Collections.Generic.IEnumerable<int>
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
val f : (Recursor<int> -> int -> int)
val cursor : Recursor<int>
val total : int
member Recursor.TryGetValue : out:byref<'a> -> bool
val value : int
property Recursor.Next: Recursor<int>
property System.Collections.Generic.IEnumerable.Recursor: Recursor<'T>
Next Version Raw view Test code New version

More information

Link:http://fssnip.net/7Uq
Posted:6 years ago
Author:manofstick
Tags: recursion , seq