#include #include #include #include # define T double # define Nil NULL #define NARGS_SEQ(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N #define NARGS(...) NARGS_SEQ(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1) #define list(...) fromArray((T []){__VA_ARGS__}, NARGS(__VA_ARGS__)) #define lambda(expr, type, args...) ({ type __fn__ (args){ return expr; }__fn__; }) // List datatype typedef struct listT { T head; struct listT* tail; }* list; // String type alias typedef char* string; // Prototypes list pure(T x); list cons(T x, list xs); list snoc(T x, list xs); list take(int k, list xs); list drop(int k, list xs); T index_(list xs, int k); T head(list xs); T last(list xs); list head_(list xs); list last_(list xs); list tail(list xs); list init(list xs); int length(list xs); list map(T (*f)(T), list xs); string show(list xs); string show_(list xs); void putStrLn(string s); void putStr(string s); void print(list xs); list fromArray (T* xs, int n); T* toArray(list xs); // Create singleton list list pure(T x) { list p = malloc(sizeof (struct listT)); p->head = x; p->tail = Nil; return p; } // Append an element before the list xs list cons(T x, list xs) { list p = malloc(sizeof (struct listT)); p->head = x; p->tail = xs; return p; } // Reverse of "cons": append after the list list snoc(T x, list xs) { list ys = last_(xs); ys->tail = pure(x); return xs; } // Take the first k elements of xs list take(int k, list xs) { if (k == 0) return xs; return cons(xs->head, take(k-1, xs->tail)); } // Remove the first k elements of xs list drop(int k, list xs) { if (k == 0) return xs; return drop(k-1, xs->tail); } // Return the k-th element of the list xs T index_(list xs, int k) { if (k == 0) return xs->head; return drop(k-1, xs->tail)->head; } // Return the first element (head) of xs T head(list xs) { return xs->head; } // Return last element of the list T last(list xs) { return last_(xs)->head; } list last_(list xs) { if (xs->tail == Nil) return xs; return last_(xs->tail); } // Return every element of xs but the last one list init(list xs) { if (xs->tail->tail == Nil) return xs; return init(xs->tail); } // Return xs "tail": everything after its first element list tail(list xs) { return xs->tail; } // Compute the length of a list int length(list xs) { if (xs->tail == Nil) return 1; return 1 + length(xs->tail); } // Apply the function f on every element of xs list map(T (*f)(T), list xs) { if (xs->tail == Nil) return pure((*f)(xs->head)); return cons((*f)(xs->head), map(f, xs->tail)); } // Convert a C array (given its size) into a list list fromArray (T* xs, int n) { if (n == 1) return pure(*xs); return cons(*xs, fromArray(xs+1, n-1)); } // Convert a list into a standard C array T* toArray(list xs) { int n = length(xs); T x, *p = malloc(n * sizeof(T)); for (int i=0; ihead); if (xs->tail == Nil) return rep; strcat(rep, ","); return strcat(rep, show_(xs->tail)); } // Print a string to stdout void putStrLn(string s) { printf("%s\n", s); } // Same as putStrLn without a terminating newline void putStr(string s) { printf("%s", s); } // Print a list to stdout void print(list xs) { putStrLn(show(xs)); } int main() { list x = list(1, 2, 3, 4); float (*f)(float) = lambda(sin(2*x)/x, float, float x); print(map(f, x)); }