Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/toptobes/haskell-in-c99-kinda
https://github.com/toptobes/haskell-in-c99-kinda
Last synced: about 9 hours ago
JSON representation
- Host: GitHub
- URL: https://github.com/toptobes/haskell-in-c99-kinda
- Owner: toptobes
- Created: 2023-08-30T22:44:18.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2023-08-31T22:37:32.000Z (over 1 year ago)
- Last Synced: 2024-11-11T21:42:55.574Z (2 months ago)
- Language: C
- Homepage:
- Size: 139 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
## Why am I doing this in C, you ask?
### because I have nothing better to do with my life
```c
/* using the double preprocessing version */CreateTypeClass(Functor unconstrained)
CreateTypeClass(Applicative constrainedBy Functor)
CreateTypeClass(Monad constrainedBy Applicative)CreateData(Maybe containing void* value; int isNothing constrainedBy Monad)
Maybe Just(int *p)
{
return (Maybe) { .isNothing = 0, .value = p };
}void* fromJust(Maybe m)
{
return m.value;
}Maybe fmapMaybe(Maybe m, void* (**fn)(void*, void*))
{
return m.isNothing ? m : Just $ Call $ fn, fromJust (m) end2
}// _Generic's not really extensible ik, might break my rules slightly and add a pre-preprocessor
// script to collect typeclass method implementations and aggregate them in the _Generics
#define fmap(self, fn) _Generic(self, Maybe: fmapMaybe(self, fn))// Using a deferred definition here so fmap can be used with $ as well
// Again could add automation script to ./run for this though that's kinda cheating
#define DEFERRED_FMAP #define fmap(self, fn) _Generic(self, Maybe: fmapMaybe(self, fn))
DEFERRED_FMAPint* add(const int amount, const int *a)
{
return Allocated (*a + amount)
}int main(int argc)
{
return deref(int) fromJust $ fmap $ Just (&argc), λ (add, 3) end2
}
```There's two slightly different (non-source-compatible) versions of the interface:
1. Use `./run` which defines `DOUBLEPP` and runs the C preprocessor twice,
enabling additional "smoothing out" of the API.
2. Run it normally w/ cmake or whatever, which also works, but provides a
slightly rougher/more manual interface.The preprocessor auto-generates functions to cast to base types in a safe manner.
If you're using mode #1, the functions will look like `Maybe2Monad` or
`Maybe2Functor`, whereas if you use mode #2, they'll look like `Maybe2MonadN`
where `N` is some number (to prevent name clashing in the event of multiple
type constraints).I'll finish this README later, I swear
TODO: more typesafety and stuff
*please, gods of C, don't come after me for this abomination*