Skip to content

Instantly share code, notes, and snippets.

@dohse
Created October 24, 2011 22:27
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 dohse/1310562 to your computer and use it in GitHub Desktop.
Save dohse/1310562 to your computer and use it in GitHub Desktop.
C monad example
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef void *(*aquire) (void *context);
struct IO {
aquire aquire;
void *context;
};
typedef struct IO (*transform) (void *context);
void *io_ident (void *context) {
return context;
}
struct IO io_return (void *context) {
struct IO res = {
.aquire = io_ident,
.context = context,
};
return res;
}
struct io_bind_context {
struct IO in;
transform transform;
};
void *io_bind_aquire (void *context_) {
struct io_bind_context *context = context_;
if (!context->in.aquire) {
return NULL;
}
struct IO res;
res = context->transform (context->in.aquire (context->in.context));
if (!res.aquire) {
printf ("Return\n");
return NULL;
}
return res.aquire (res.context);
}
struct IO io_bind (struct IO in, transform transform) {
struct io_bind_context *context = malloc (sizeof (*context));
context->in = in;
context->transform = transform;
struct IO res = {
.aquire = io_bind_aquire,
.context = context
};
return res;
}
void *do_print (void *context) {
printf ("%s\n", (char *) context);
return NULL;
}
struct IO io_print (char *value) {
struct IO res = {
.aquire = do_print,
.context = value
};
return res;
}
void *do_read_line (void *context) {
(void) context;
char *in = malloc (1024);
if (!fgets (in, 1024, stdin)) {
free (in);
return NULL;
}
in[strlen (in) - 1] = 0;
return in;
}
struct IO io_read_line () {
struct IO res = {
.aquire = do_read_line,
.context = NULL
};
return res;
}
struct IO f (void *context) {
char *buf;
int res;
res = asprintf(&buf, "Sein Name ist '%s'", (char *) context);
(void) res;
return io_print (buf);
}
struct IO r (void *context) {
(void) context;
return io_read_line ();
}
int main() {
struct IO p = io_print ((char *) "Wie ist dein Name?");
struct IO res = io_bind (io_bind (p, r), f);
res.aquire (res.context);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment