Skip to content

Instantly share code, notes, and snippets.

@aisamanra
Last active April 24, 2017 09:28
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aisamanra/3d2305e12a1699aaae0eb1039496389b to your computer and use it in GitHub Desktop.
Save aisamanra/3d2305e12a1699aaae0eb1039496389b to your computer and use it in GitHub Desktop.
#include <stdio.h>
typedef struct {
int tag;
union {
int l;
struct {
char* fst;
float snd;
} r;
} payload;
} either;
#define tag_left 1
void
mk_left(either *e, int l)
{
e->tag = tag_left;
e->payload.l = l;
}
void
from_left(either e, void f(int))
{
f(e.payload.l);
}
#define tag_right 2
void
mk_right(either* e, char* r, float f)
{
e->tag = tag_right;
e->payload.r.fst = r;
e->payload.r.snd = f;
}
void
from_right(either e, void f(char*, float))
{
f(e.payload.r.fst, e.payload.r.snd);
}
#define match(expr) { typeof(expr) _expr = expr; switch(_expr.tag) {
#define end_match } }
#define case_(constr, bindings) } break; case(tag_##constr): { auto void _handler bindings; from_##constr(_expr, _handler); void _handler bindings
int main(int argc, char* argv[])
{
either e1, e2;
mk_right(&e1, "argl", 7.0);
mk_left(&e2, 22);
match(e1) {
case_(left, (int n)) {
printf("left %d\n", n);
}
case_(right, (char* s, float f)) {
printf("right %s %f\n", s, f);
}
} end_match;
match(e2) {
case_(left, (int n)) {
printf("left %d\n", n);
}
case_(right, (char* s, float f)) {
printf("right %s %f\n", s, f);
}
} end_match;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment