22 people like it.

A Lazy fixed-point combinator

x = f(x) encoded in F#

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
let force (value : Lazy<_>) = value.Force()

let fix f = let rec x = lazy (f x) in x

// Examples
let fac = fix (fun f x -> if x = 0 then 1 else x * force f (x - 1) )
let nums = fix (fun v -> seq { yield 0; yield! Seq.map ((+) 1) (force v) }) 

force fac 10 // 10! = 3628800
Seq.take 10 (force nums) // seq [0; 1; 2; 3; ...]
val force : value:Lazy<'a> -> 'a

Full name: Script.force
val value : Lazy<'a>
Multiple items
active recognizer Lazy: Lazy<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.( |Lazy| )

--------------------
type Lazy<'T> = System.Lazy<'T>

Full name: Microsoft.FSharp.Control.Lazy<_>
member System.Lazy.Force : unit -> 'T
val fix : f:(Lazy<'a> -> 'a) -> Lazy<'a>

Full name: Script.fix
val f : (Lazy<'a> -> 'a)
val x : Lazy<'a>
val fac : Lazy<(int -> int)>

Full name: Script.fac
val f : Lazy<(int -> int)>
val x : int
val nums : Lazy<seq<int>>

Full name: Script.nums
val v : Lazy<seq<int>>
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

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

--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
module Seq

from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
val take : count:int -> source:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.take
Raw view Test code New version

More information

Link:http://fssnip.net/36
Posted:13 years ago
Author:Nick Palladinos
Tags: lazy , fixed-point combinator , haskell