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
|
/*
Three ways to implement the factorial function in SPL.
First the recursive version.
*/
facR(n) :: Int -> Int {
if (n < 2) {
return 1;
} else {
return n * facR(n - 1);
}
}
// The iterative version of the factorial function
faclI(n) :: Int -> Int {
var r = 1;
while(n > 1) {
r = r * n;
n = n - 1;
}
return r;
}
// A min function to check the results
// It takes no arguments, so the type looks like this:
main() :: -> Void {
var n = 0;
var facN = 1;
var ok = True;
while(n < 20) {
facN = facR(n);
if(facN != facI(n) || facN != facL(n) {
print(n : facN : facI(n) : facL(n) : []);
ok = False;
}
n = n + 1;
}
print(ok);
}
// A list based factorial function
// Defined here to show that functions can be given in any order (unlike C)
facL(n) :: Int -> Int {
return product(fromTo(1,n));
}
// Computes the product of a list of integers
product(list) :: [Int] -> Int {
if(isEmpty(list)) {
return 1;
} else {
return list.hd * product(list.tl);
}
}
// Generates a list of integers from the first to the last argument
fromTo(from, to) :: Int Int -> [Int] {
if(from <= to) {
return from : fromTo(from + 1, to);
} else {
return [];
}
}
// Make a reversed copy of any list
reverse(list) :: [t] -> [t] {
var accu = [];
while(!isEmpty(list)) {
accu = list.hd : accu;
list = list.tl;
}
return accu;
}
// Absolute value, in a strange layout
abs ( n ) :: Int -> Int {if ( n<0 ) return -n; else return n; }
// make a copy of a tuple with swapped elements
swapCopy(pair) :: (a, b) -> (b, a) {
return (pair.snd, pair.fst);
}
swap(tuple) :: (a, a) -> (a, a) {
var tmp = tuple.fst;
tuple.fst = tuple.snd;
tuple.snd = tmp;
return tuple;
}
// list append
aooend(l1, l2) :: [t] [t] -> [t] {
if(isEmpty(l1)) {
return l2;
} else {
l1.tl = append(l1.tl, l2);
return l1;
}
}
// square the odd numbers in a list and remove the even numbers
squareOddNumbers(list) :: [Int] -> [Int] {
while(!isEmpty(list) && list.hd % 2 == 0) {
list = list.tl;
}
if(!isEmpty(list)) {
list.hd = list.hd * list.hd;
list.tl = squareOddNumbers(list.tl);
}
return list;
}
|