Skip to content

Instantly share code, notes, and snippets.

@back2dos
Created September 13, 2013 11:50
Show Gist options
  • Select an option

  • Save back2dos/6549682 to your computer and use it in GitHub Desktop.

Select an option

Save back2dos/6549682 to your computer and use it in GitHub Desktop.
Fun with chains.
package ;
using Main;
typedef Future<T> = (T->Void)->Void;
typedef Chain<T> = Future<Option<{ data: T, next: Chain<T>}>>;
class Main {
static function lazy<A>(g:Void->A) {
var done = false,
result = null;
return function () {
if (!done) {
done = true;
result = g();
}
return result;
}
}
static function generateChain<A>(g:Void->Option<A>):Chain<A> {
var calc = lazy(g),
next = lazy(generateChain.bind(g));
return
function (cb) switch calc() {
case None: cb(None);
case Some(data): cb(Some({ data: data, next: next() }));
}
}
static function sliceChain<A>(chain:Chain<A>, length:Int):Chain<A>
return function (cb)
if (length <= 0) cb(None);
else chain(function (link) switch link {
case None: cb(None);
case Some({ data: data, next: next }):
cb(Some({ data: data, next: sliceChain(next, length - 1)}));
});
static function iter<A>(chain:Chain<A>, cb:A->Void)
chain(function (link) switch link {
case None:
case Some({ data: data, next: next }):
cb(data);
iter(next, cb);
});
static function fib() {
var a = 0,
b = 1;
return (function () {
var old = a;
if (a < 0 || a > (1 << 30)) return None;//out of int bounds
trace('generate $a');
a += b;
b = old;
return Some(old);
}).generateChain();
}
static function main() {
var c = fib();
var first4 = c.sliceChain(4);
trace('---- first 4 #1');
first4.iter(function (x) trace(x));
trace('---- first 4 #2');
first4.iter(function (x) trace(x));
trace('---- all #1');
c.iter(function (x) trace(x));
trace('---- all #2');
c.iter(function (x) trace(x));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment