Skip to content

Instantly share code, notes, and snippets.

@cblp
Last active September 28, 2022 18:01
Show Gist options
  • Save cblp/e8184d0457d4345a3cb63d70ddfe3a56 to your computer and use it in GitHub Desktop.
Save cblp/e8184d0457d4345a3cb63d70ddfe3a56 to your computer and use it in GitHub Desktop.
#include <iostream>
using namespace std;
#define LAZY(expression) Lazy<Cons>{[=]{ return expression.get(); }}
#define LAZY_REF(expression) Lazy<Cons>{[&]{ return expression.get(); }}
template<typename T>
class Lazy {
private:
mutable shared_ptr<T> value;
function<shared_ptr<T>()> thunk;
public:
Lazy(shared_ptr<T> value) : value(value) {}
Lazy(function<shared_ptr<T>()> thunk) : thunk(thunk) {}
shared_ptr<T> get() const {
if (not value)
value = thunk();
return value;
}
shared_ptr<T> operator->() const { return get(); }
};
struct Cons {
intmax_t head;
Lazy<Cons> tail;
Cons(intmax_t head, Lazy<Cons> tail) : head(head), tail(tail) {}
};
Lazy<Cons> cons(intmax_t head, Lazy<Cons> tail) {
return make_shared<Cons>(head, tail);
}
Lazy<Cons> tail(Lazy<Cons> c) { return LAZY(c->tail); }
Lazy<Cons> zipWithPlus(Lazy<Cons> xs, Lazy<Cons> ys) {
return cons(xs->head + ys->head, LAZY(zipWithPlus(tail(xs), tail(ys))));
}
int main() {
Lazy<Cons> const fibs =
cons(0, cons(1, LAZY_REF(zipWithPlus(fibs, tail(fibs)))));
shared_ptr<Cons> it = fibs.get();
for (int i = 0; i < 90; ++i, it = it->tail.get())
cout << it->head << endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment