Skip to content

Instantly share code, notes, and snippets.

@guipn
Created April 18, 2012 05:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save guipn/2411202 to your computer and use it in GitHub Desktop.
Save guipn/2411202 to your computer and use it in GitHub Desktop.
Not Haskell
// gcc -std=c99 -Wall -Wextra -pedantic list.c -o list
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
void *value;
struct node *tail;
} list_t;
list_t *empty(void)
{
return NULL;
}
int is_empty(list_t *head)
{
return head == empty();
}
list_t *next(list_t *head)
{
if (is_empty(head))
{
perror(__func__);
}
return head->tail;
}
list_t *cons(void *value, list_t *tail)
{
list_t *new = malloc(sizeof *new);
if (!new)
{
perror("malloc");
}
new->value = value;
new->tail = tail;
return new;
}
void destroy(list_t *head)
{
for (list_t *cur = empty(); !is_empty(head); head = next(head))
{
cur = head;
free(cur);
}
}
list_t *take(size_t n, list_t *head)
{
if (is_empty(head) || n == 0)
{
return empty();
}
list_t *taken = head,
*last_taken = empty();
while (n > 0 && !is_empty(head))
{
last_taken = head;
head = next(head);
n--;
}
last_taken->tail = empty();
return taken;
}
list_t *drop(list_t *head, size_t n)
{
list_t *dropped = head;
while (n > 0 && !is_empty(next(dropped)))
{
dropped = next(dropped);
n--;
}
return (n > 0) ? empty() : dropped;
}
void print_ints(list_t *head)
{
if (is_empty(head))
{
puts("()");
}
else
{
printf("(");
while (!is_empty(head) && !is_empty(next(head)))
{
printf("%d, ", *((int *) head->value));
head = next(head);
}
printf("%d)\n", *((int *) head->value));
}
}
int main(void)
{
int a = 1, b = 2, c = 3, d = 4;
list_t *list = cons(&a, cons(&b, cons(&c, cons(&d, empty())))),
*dropped = drop(list, 2);
print_ints(dropped);
destroy(list);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment