Last active
December 27, 2015 20:39
-
-
Save geoffrasb/7385956 to your computer and use it in GitHub Desktop.
little typing sys
This file contains hidden or 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
/* | |
for each type: | |
1. Define in Type as "newtype_t". | |
2. Define constructors. | |
If struct is needed, name it "Newtype_t". | |
3. Define "_deNewtype", which typed as "Data -> void". | |
*/ | |
#include<assert.h> | |
#define tc(d,t) assert((d).type == (t)); | |
#define tc2(d1,d2,t) assert((d1).type == (t) && (d2).type == (t)) | |
#define tc3(d1,d2,d3,t) assert((d1).type == (t) && (d2).type == (t) && (d3).type == (t)) | |
#define nil NULL | |
typedef enum | |
{ bottom_t | |
, boolean_t | |
, pair_t | |
, int_t | |
, cons_t | |
} Type; | |
typedef struct Data{ | |
Type type; | |
void* cont; | |
} Data; | |
void _dePair(Data); | |
void _deInt(Data); | |
void _deCons(Data); | |
void deData(Data d){ | |
switch(d.type){ | |
case int_t: _deInt(d); break; | |
case pair_t: _dePair(d); break; | |
case cons_t: _deCons(d); break; | |
default: | |
break; } } | |
Data Bot(){ | |
Data res = { bottom_t, NULL }; | |
return res; } | |
int isBot(Data d){ | |
if(d.type==bottom_t) return 1; | |
else return 0; } | |
Data True(){ | |
Data res = {boolean_t, (void*)1}; | |
return res; } | |
Data False(){ | |
Data res = {boolean_t, (void*)0}; | |
return res; } | |
/* | |
int prop(Data d){ tc(d,boolean_t); | |
return (int)d.cont; } | |
*/ | |
Data Int(int a){ | |
int *i = (int*)malloc(sizeof(int)); | |
*i = a; | |
Data res = {int_t, (void*)i}; | |
return res; } | |
void _deInt(Data d){ tc(d,int_t); | |
free((int*)d.cont); } | |
int pureInt(Data d){ tc(d,int_t); | |
return *((int*)d.cont); } | |
typedef struct Pair_t{ | |
Data fst; | |
Data snd; | |
} Pair_t; | |
Data Pair(Data fst,Data snd){ | |
Pair_t*p = (Pair_t*)malloc(sizeof(Pair_t)); | |
Data res = {pair_t, (void*)p}; | |
return res; } | |
void _dePair(Data d){ tc(d,pair_t); | |
deData(((Pair_t*)(d.cont))->fst); | |
deData(((Pair_t*)(d.cont))->snd); | |
free((Pair_t*)(d.cont)); } | |
Data fst(Data p){ tc(p,pair_t); | |
return ((Pair_t*)p.cont) -> fst; } | |
Data snd(Data p){ tc(p,pair_t); | |
return ((Pair_t*)p.cont) -> snd; } | |
typedef struct Cons_t{ | |
Data car; | |
Data cdr; | |
} Cons_t; | |
Data | |
Empty(){ | |
Data res = { cons_t, nil }; | |
return res; } | |
Data | |
Cons(Data a, Data c){ tc(c,cons_t); | |
Cons_t*nc = (Cons_t*)malloc(sizeof(Cons_t)); | |
nc->car = a; | |
nc->cdr = c; | |
Data res = { cons_t, (void*)nc }; | |
return res; } | |
int | |
isEmpty(Data c){ tc(c,cons_t); | |
if(c.cont==nil) return 1; | |
else return 0; } | |
Data | |
car(Data c){ tc(c,cons_t); | |
if(isEmpty(c)) return Bot(); | |
else return ((Cons_t*)c.cont)->car; } | |
Data | |
cdr(Data c){ tc(c,cons_t); | |
if(isEmpty(c)) return Bot(); | |
else return ((Cons_t*)c.cont)->cdr; } | |
void | |
_deCons(Data c){ tc(c,cons_t); | |
if(!isEmpty(c)){ | |
deData(car(c)); | |
free((Cons_t*)c.cont); | |
_deCons(cdr(c)); } } | |
Data | |
setAsLast(Data c){ tc(c,cons_t); | |
if(!isEmpty(c)){ | |
((Cons_t*)c.cont)->cdr = Empty(); } | |
return c;} | |
Data | |
setCar(Data c,Data a){ tc(c,cons_t); | |
if(!isEmpty(c)){ | |
((Cons_t*)c.cont)->car = a;} | |
return c; } | |
Data | |
setCdr(Data c, Data c1){ tc2(c,c1,cons_t); | |
if(!isEmpty(c)){ | |
((Cons_t*)c.cont)->cdr = c1; } | |
return c; } | |
/* mapping and folding patterns*/ | |
/* map f lst => | |
while(!isEmpty(lst)){ | |
*** | |
lst = cdr(lst) } | |
*/ | |
/* fold f seed lst => | |
Data seed; | |
while(!isEmpty(lst)){ | |
seed = f seed car(lst) | |
lst = cdr(lst) } | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment