1 module fptools.native;
2 
3 /++
4     take - Usage : take(3, [1,2,3,4,5]) == [1,2,3]
5 +/
6 T[] take(T) (int n, T[] list) {
7     return list[0 .. n];
8 }
9 
10 /++
11     takeWhile - Usage : takeWhile!int(x => x < 3, seq(1,10)) == [1,2]
12 +/
13 T[] takeWhile(T) (bool delegate(T) p, T[] list) {
14     auto n = 0;
15     T[] result;
16     while(p(list[n])) {
17         result ~= list[n];
18         n++;
19     }
20     return result;
21 }
22 
23 /++
24     map - Usage : map!int(x => x + 3, seq(1,4)) == [4, 5, 6, 7]
25 +/
26 T[] map(T) (T delegate(T) f, T[] list) {
27     T[] result; result.length = list.length;
28     foreach(i, ref x; list) {
29         result[i] = f(x);
30     }
31     return result;
32 }
33 
34 /++
35     drop - Usage : drop(3, seq(1,5)) == [4,5]
36 +/
37 T[] drop(T) (int n, T[] list) {
38     assert(n <= list.length, "Exceed drop range");
39     return list[n .. $];
40 }
41 
42 /++
43     dropWhile - Usage : dropWhile!int(x => x < 3, seq(1,5)) == [3,4,5]
44 +/
45 T[] dropWhile(T) (bool delegate(T) p, T[] list) {
46     auto n = 0;
47     while(p(list[n])) {
48         n++;
49     }
50     return list[n .. $];
51 }
52 
53 /++
54     reduce
55 +/
56 T reduce(T) (T delegate(T, T) op, T[] list) {
57     T result = list[0];
58     foreach(i; 1 .. list.length) {
59         result = op(result, list[i]); 
60     }
61     return result;
62 }
63 
64 /++
65     filter - Usage : filter!int(x => x%2 == 0, seq(1,10)) == [2,4,6,8,10]
66 +/
67 T[] filter(T) (bool delegate(T) p, T[] list) {
68     auto n = 0;
69     T[] result;
70     foreach(x; list) {
71         if (p(x)) {
72             result ~= x;
73         }
74     }
75     return result;
76 }
77 
78 /++
79     zipWith - Usage: zipWith((x, y) => x + y, [1,2], [3,4]) == [4, 6]
80 +/
81 T[] zipWith(T) (T delegate(T, T) op, T[] t1, T[] t2) {
82     import std.algorithm.comparison : min;
83     
84     auto m = min(t1.length, t2.length);
85     T[] result;
86     result.length = m;
87     foreach(i; 0 .. m) {
88         result[i] = op(t1[i], t2[i]);
89     }
90     return result;
91 }
92 
93 /++
94     all - Usage: all(x => x%2 == 0, [2, 4, 6]) == true
95 +/
96 bool all(T) (bool delegate(T) p, T[] list) {
97     foreach(x; list) {
98         if (!p(x)) {
99             return false;
100         }
101     }
102     return true;
103 }
104 
105 /++
106     any - Usage: any(x => x%2 == 0, [2, 5, 7]) == true
107 +/
108 bool any(T) (bool delegate(T) p, T[] list) {
109     foreach(x; list) {
110         if (p(x)) {
111             return true;
112         }
113     }
114     return false;
115 }