A list/Makefile => list/Makefile +14 -0
@@ 0,0 1,14 @@
+.POSIX:
+CC = cc
+CFLAGS = -std=c99 -Wpedantic -Wall -Wextra -O3
+LDFLAGS =
+
+all: list
+
+list: list.o
+ $(CC) $(CFLAGS) -o main list.o $(LDFLAGS)
+
+list.o: list.c
+
+clean:
+ rm -f list list.o
A list/list.c => list/list.c +124 -0
@@ 0,0 1,124 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define NUM_ELEMS 15
+
+/* Data constructor names */
+enum list_const {EMPTY, CONS};
+
+/* Actual sum data type */
+struct list {
+ enum list_const type;
+ struct data {
+ int num;
+ struct list *next;
+ } data;
+};
+
+/* Empty list constructor */
+struct list *
+make_empty(struct list *lst)
+{
+ lst->type = EMPTY;
+ lst->data = (struct data) {0};
+
+ return lst;
+}
+
+/* Cons constructor */
+struct list *
+cons(int a, struct list *lst)
+{
+ if (lst) {
+ struct list *new = malloc(sizeof(struct list));
+
+ if (new) {
+ new->type = CONS;
+ new->data.num = a;
+ new->data.next = lst;
+ lst = new;
+ }
+ }
+
+ return lst;
+}
+
+int
+length(struct list *lst)
+{
+ if (lst) {
+ switch (lst->type) {
+ case EMPTY:
+ return 0;
+ case CONS:
+ /* Could use tail recursion */
+ return 1 + length(lst->data.next);
+ default:
+ fprintf(stderr, "Non-exhaustive patterns in function "
+ "%s\n", __func__);
+ }
+ }
+
+ return -1;
+}
+
+struct list *
+map(int (*fun)(int a), struct list *lst)
+{
+ if (lst) {
+ struct list *tmp = lst;
+ while (tmp) {
+ tmp->data.num = fun(tmp->data.num);
+ tmp = tmp->data.next;
+ }
+ }
+
+ return lst;
+}
+
+void
+print_list(struct list *lst)
+{
+ switch (lst->type) {
+ case EMPTY:
+ puts("[]");
+ break;
+ case CONS:
+ printf("%d,", lst->data.num);
+ print_list(lst->data.next);
+ }
+}
+
+int
+sum(int a)
+{
+ return a+1;
+}
+
+int
+main(void)
+{
+ struct list *lst = malloc(sizeof(struct list));
+ if (!lst) return EXIT_FAILURE;
+
+ make_empty(lst);
+ print_list(lst);
+
+ for (int i = 1; i <= NUM_ELEMS; i++) {
+ lst = cons(i, lst);
+ }
+
+ print_list(lst);
+ printf("Length %d\n", length(lst));
+
+ map(&sum, lst);
+ print_list(lst);
+
+ struct list *curr = 0;
+ while ((curr = lst)) {
+ lst = lst->data.next;
+ free(curr);
+ }
+
+ return EXIT_SUCCESS;
+}