Skip to content

Instantly share code, notes, and snippets.

@Sintrastes
Created October 21, 2021 12:58
Show Gist options
  • Save Sintrastes/9773f6b41345e6a3328997244515f58a to your computer and use it in GitHub Desktop.
Save Sintrastes/9773f6b41345e6a3328997244515f58a to your computer and use it in GitHub Desktop.
Comonads in C++.
//
// Comonads.cpp: Comonads in C++
//
// Author: Nathan Bedell
//
//
// "Your scientists were so preoccupied with whether or not they could, they didn't stop
// to think if they should."
//
#include <iostream>
#include <string>
template <template <typename> class w>
struct Comonad {
template <typename a>
static a& extract(const w<a>);
template <typename a>
static w<w<a>>& duplicate(w<a>);
};
template <typename a, typename b>
struct Store {
a internalState;
b (*view)(a);
};
template <typename e, typename a>
struct Moore {
a internalState;
Moore<e,a> (*onEvent)(e);
};
template <template <typename> class f, typename a>
struct Cofree {
a state;
f<Cofree<f, a>> next;
};
// Note: I'm not sure if this is right.
template <typename A, typename R>
struct CalculatorFVisitor {
R onEnterSymbol(char* symbol, A (*rest)(A));
R onEnterNumber(int number, A (*rest)(A));
R onQueryResult(int number, int (*rest)(A));
};
template <typename A>
struct CalculatorF {
template <typename R>
R accept(CalculatorFVisitor<A, R> visitor);
};
template <typename A>
using Calculator = Cofree<CalculatorF, A>;
/*
Calculator<int> calculator(int state) {
return {
.state = state,
.next = {
// Generic lambda not accepted here?
.accept = []<typename R>(CalculatorFVisitor<int, R> visitor) {
return visitor.onEnterSymbol()
}
}
}
}
*/
int main() {
Store<int,int> store = {
.internalState = 40,
.view = [](auto x) { return x + 2; }
};
std::cout << std::to_string(store.view(store.internalState));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment