-
Notifications
You must be signed in to change notification settings - Fork 17
/
russo.1ml
102 lines (87 loc) · 2.29 KB
/
russo.1ml
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
;; Dynamically-Sized Functional Arrays
;; After Russo 1998, Types for Modules, Section 7.3
type ARRAY =
{
type array a;
dim : int;
new 'a : a -> array a;
sub 'a : array a -> int -> a;
update 'a : array a -> int -> a -> array a;
};
ArrayZero =
{
type array a = a;
dim = 1;
new x = x;
sub a i = a;
update a i x = x;
};
ArraySucc (A : ARRAY) =
{
type array a = (A.array a, A.array a);
dim = 2 * A.dim;
new x = (A.new x, A.new x);
sub (a : array _) i = A.sub (if i % 2 == 0 then a.1 else a.2) (i / 2);
update (a : array _) i x =
if i % 2 == 0
then (A.update (a.1) (i / 2) x, a.2)
else (a.1, A.update (a.2) (i / 2) x);
};
MkArray = rec (mkArray : int -> ARRAY) => fun n =>
if n == 0 then ArrayZero else ArraySucc (mkArray (n - 1)) : ARRAY;
printArray 't (A : ARRAY) (pr : t -> ()) a =
let loop = rec loop => fun i =>
if i == A.dim then print "\n"
else (pr (A.sub a i) ; print " " ; loop (i + 1))
in loop 0;
A32 = MkArray 5;
a = A32.new 0;
do printArray A32 (Int.print) a;
a = A32.update a 17 1;
a = A32.update a 11 2;
a = A32.update a 15 3;
a = A32.update a 27 4;
a = A32.update a 1 5;
a = A32.update a 0 6;
do printArray A32 (Int.print) a;
;; Sieve of Erathostenes
;; After Russo 1998, Types for Modules, Section 7.2
type STREAM =
{
type state;
start : state;
next : state -> state;
value : state -> int;
};
divides k n =
let loop = rec loop => fun i => (i * k == n) or ((i * k < n) and loop (i + 1))
in loop 1;
sift (S : STREAM) :> STREAM =
{
type state = S.state;
divisor = S.value (S.start);
filter = rec filter => fun s =>
if divides divisor (S.value s) then filter (S.next s) else s;
start = filter (S.start);
next s = filter (S.next s);
value = S.value;
};
Sieve :> STREAM =
{
type state = wrap STREAM;
start = wrap
{
type state = int;
start = 2;
next n = n + 1;
value s = s;
} : state;
next (s : state) = let S = unwrap s : state in wrap sift S : state;
value (s : state) = let S = unwrap s : state in S.value (S.start);
};
nthstate = rec (nthstate : int -> Sieve.state) => fun n =>
if n == 0 then Sieve.start else Sieve.next (nthstate (n -1));
nthprime n = Sieve.value (nthstate n);
printprimes = rec loop => fun n =>
if n == 0 then () else (loop (n - 1) ; Int.print (nthprime n) ; print "\n");
do printprimes 20;