-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathiterator.fsx
More file actions
executable file
·113 lines (97 loc) · 2.81 KB
/
iterator.fsx
File metadata and controls
executable file
·113 lines (97 loc) · 2.81 KB
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
module Iterator =
type Iter<'a> = Iter of (unit -> 'a option)
type Iterator<'a> = Iterator of (unit -> Iter<'a>)
module Iter =
let get (Iterator iter) = iter ()
let next (Iter iter) = iter ()
let unfold f (acc:'State) =
Iterator(fun () ->
let mutable acc = Some acc
Iter(fun () ->
if Option.isSome acc then
let x = acc.Value
match f x with
| Some (value,nextAcc) ->
acc <- Some nextAcc
Some value
| None ->
acc <- None
None
else
None
)
)
let fold f (acc:'State) iter =
let iter = Iter.get iter
let rec loop acc =
match Iter.next iter with
| Some x -> loop (f acc x)
| None -> acc
loop acc
let iter f iter =
let iter = Iter.get iter
let rec loop () =
match Iter.next iter with
| Some x -> f x; loop ()
| None -> ()
loop ()
let range start stop =
let folder acc =
if acc <= stop
then Some (acc, acc+1)
else None
unfold folder start
let take x iter =
Iterator(fun () ->
let iter = Iter.get iter
let mutable amount = 0
Iter(fun () ->
if amount < x then
amount <- amount + 1
Iter.next iter
else
None
)
)
let inline sum iter =
fold (+) LanguagePrimitives.GenericZero iter
let map f iter =
Iterator(fun () ->
let iter = Iter.get iter
Iter(fun () ->
Option.map f (Iter.next iter)
)
)
let rev (xs:Iterator<'a>) =
Iterator(fun () ->
let stack = System.Collections.Generic.Stack ()
iter (stack.Push) xs
Iter(fun () ->
let mutable result = Unchecked.defaultof<'a>
match stack.TryPop(&result) with
| true -> Some result
| false -> None
)
)
let r = Iterator.range 0 100_000_000
let xs = Iterator.take 10 r
let ys = Iterator.take 5 r
xs |> Iterator.iter (fun x ->
printfn "%d" x
)
Iterator.range 100 2000
|> Iterator.take 10
|> Iterator.map (fun x -> x, sqrt (float x))
|> Iterator.iter (fun (x,sq) -> printfn "%d -> %f" x sq)
Iterator.range 100 2000
|> Iterator.rev
|> Iterator.take 10
|> Iterator.sum
|> printfn "Sum: %d"
Iterator.range 100 2000
|> Iterator.rev
|> Iterator.take 10
|> Iterator.iter (printfn "%d")
ys |> Iterator.iter (fun x ->
printfn "%d" x
)