Created
March 17, 2014 07:20
-
-
Save shwars/9595230 to your computer and use it in GitHub Desktop.
Demonstration of creating generators in F#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Simple counter | |
type cell = { mutable content : int } | |
let new_counter n = | |
let x :cell = { content = n } | |
fun () -> | |
(x.content <- x.content+1; x.content) | |
// The same, using F# refs | |
let new_counter' n = | |
let x = ref n | |
fun () -> | |
(x:=!x+1; !x) | |
// Unfolding generator | |
let generate f initial_state = | |
let x = ref initial_state | |
fun () -> | |
(x:=f !x; !x) | |
// How to generate fibonacci sequence | |
let fibgen = generate (fun (u,v) -> (u+v,u)) (1,1) | |
// Implementation of classical Higher-order functions using generators | |
let map f gen = | |
fun () -> | |
f (gen()) | |
let take n gen = | |
let rec take' acc n = | |
if n>0 then take' (gen()::acc) (n-1) | |
else acc | |
take' [] n | |
fibgen |> map fst |> take 10 | |
let rec filter p gen = | |
fun () -> | |
let x = gen() | |
if p x then x | |
else (filter p gen)() | |
// Find first fibonacci number that is divisible by 256 | |
let fibgen = generate (fun (u,v) -> (u+v,u)) (1I,1I) | |
fibgen |> map fst |> filter (fun x->x%256I=0I) |> take 5 | |
// The same using F# seq | |
let swap f x y = f y x | |
Seq.unfold (fun (u,v) -> Some(v,(u+v,u))) (1I,1I) | |
|> Seq.filter (swap(%)256I >> ((=)0I)) |> Seq.head |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment