-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathML_sequences.sml
79 lines (67 loc) · 2.89 KB
/
ML_sequences.sml
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
datatype ('a, 'b) heterolist = HNil
| HCons of 'a * ('b, 'a) heterolist;
(* Example:
build4 ("x",1,"y",2) = ["x",1,"y",2];
(not syntactically correct, since heterolist cannot be written with []) *)
fun build4 (x,one,y,two) = HCons(x, HCons(one, HCons(y, HCons(two, HNil))));
(* Example:
unzip ["x", 1, "y", 2] = (["x", "y"], [1,2]);
(not syntactically correct, since heterolist cannot be written with []) *)
local
fun unzip_a HNil acc = acc
| unzip_a (HCons(a, bas)) (acc_a, acc_b) = unzip_b bas (acc_a @ [a], acc_b)
and unzip_b HNil acc = acc
| unzip_b (HCons(b, abs)) (acc_a, acc_b) = unzip_a abs (acc_a, acc_b @ [b])
in
fun unzip hlist = unzip_a hlist ([], [])
end;
(* Example:
zip (["x", "y"], [1,2]) = ["x", 1, "y", 2];
(not syntactically correct, since heterolist cannot be written with []) *)
local
fun zip_a ([], []) = HNil
| zip_a ([], _) = raise Empty
| zip_a (a::ass, bs) = HCons(a, zip_b(ass, bs))
and zip_b ([], []) = HNil
| zip_b (_, []) = raise Empty
| zip_b (ass, b::bs) = HCons(b, zip_a(ass, bs))
in
fun zip two_hlists = zip_a two_hlists
end;
(* One direction sequences *)
exception EmptySeq;
datatype 'a seq = Nil | Cons of 'a * (unit-> 'a seq);
fun head(Cons(x,_)) = x | head Nil = raise EmptySeq;
fun tail(Cons(_,xf)) = xf() | tail Nil = raise EmptySeq;
(* Bidirectional sequences *)
datatype direction = Back | Forward;
datatype 'a bseq = bNil | bCons of 'a * (direction -> 'a bseq);
fun bHead(bCons(x,_)) = x | bHead bNil = raise EmptySeq;
fun bForward(bCons(_,xf)) = xf(Forward) | bForward bNil = raise EmptySeq;
fun bBack(bCons(_,xf)) = xf(Back) | bBack bNil = raise EmptySeq;
(* Creates Bidirectional sequence of consequtive integers with n as starting pivot *)
fun intbseq n = bCons(n, fn dir =>
(case dir of Forward => intbseq (n+1) | Back => intbseq (n-1)));
fun bmap _ bNil = bNil
| bmap f (bCons(x, xf)) = bCons(f x, fn dir => bmap f (xf dir));
fun bfilter _ _ bNil = bNil
| bfilter pred dir (bCons(x, xf)) = if pred x then
bCons(x, fn dir => bfilter pred dir (xf dir))
else bfilter pred dir (xf dir);
fun seq2bseq _ Nil = bNil |
seq2bseq Nil (Cons(fw, fwf)) = bCons(fw, fn dir =>
case dir of Forward => seq2bseq (Cons(fw, fn () => Nil)) (fwf()) |
Back => bNil) |
seq2bseq (Cons(bw, bwf)) (Cons(fw, fwf)) = bCons(fw, fn dir =>
case dir of Forward => seq2bseq (Cons(fw, fn () => Cons(bw, bwf))) (fwf()) |
Back => seq2bseq (bwf()) (Cons(bw, fn () => Cons(fw, fwf))));
local
exception NonPositiveJump;
fun jmp bNil _ _ = raise Empty
| jmp biseq 0 _ = biseq
| jmp (bCons(x, xf)) n dir = jmp (xf dir) (n-1) dir;
in
fun bSeqJump bNil _ = raise Empty
| bSeqJump (bCons(x, xf)) jump = if jump <= 0 then raise NonPositiveJump else
bCons(x, fn dir => bSeqJump (jmp (bCons(x, xf)) jump dir) jump)
end;