

include <stdio.h>



typedef struct {

int something;

int just;

} MaybeInt;



MaybeInt returnMaybe(int i)

{

MaybeInt r;

r.something = 1;

r.just = i;

return r;

}



MaybeInt nothing()

{

MaybeInt r;

r.something = 0;

return r;

}



MaybeInt bind(MaybeInt (*f)(int),MaybeInt x)

{

if (x.something)

{

return f(x.just);

} else

{

return nothing();

}

}



MaybeInt print(int i)

{

int written = printf("%d

",i);

if (written>=0)

{

return returnMaybe(written);

} else

{

return nothing();

}

}



MaybeInt printplus_bad(int i)

{

MaybeInt x = print(i);

return print(x.just); /* cheating! */

}



MaybeInt printplus(int i)

{

MaybeInt x = print(i);

return bind(print,x);

}



This is a quick followup to a post on reddit . This time a crude approximation to the Maybe monad implemented in C:Again the idea is that printplus() is a version of printplus_bad() that uses just the two function bind/return interface to the MaybeInt type to achieve its effect. This time, instead of simply tainting IO with a particular type, the Maybe monad is able to deal gracefully with failure. If, for some obscure reason, printf() fails, returning an integer less than zero, it returns an object representing this fact. If, as in printplus(), you have two calls to print() in a row, bind() handles all the plumbing for you automatically. The really important thing is this: the implementation of printplus() is identical to my previous example, and yet the semantics is quite different because printplus() is able to bail out early. This bailing out is completely hidden inside bind().I hope that this gives some hint of what monads can do to even hardcore non-functional programmers. If not, I'll probably write another example soon.(Remember of course that this isn't meant to be practical code. It was a response to someone who wanted to at least some some C code for monads to get an idea of what they're about.)

Labels: monad