Created
October 24, 2011 22:27
-
-
Save dohse/1310562 to your computer and use it in GitHub Desktop.
C monad example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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