Curried lazys
This commit is contained in:
+14
-14
@@ -1,30 +1,30 @@
|
||||
import { Lazy, V, _ } from './core';
|
||||
import { Lazy, Q, V, _ } from './core';
|
||||
|
||||
export type Bool = Lazy<<T extends V>(t: T) => (f: T) => T>;
|
||||
export type Bool = Lazy<<T extends V>(t: T) => Lazy<(f: T) => T>>;
|
||||
|
||||
export const True: Bool
|
||||
= _(t => _ => t) as Bool;
|
||||
= _(t => _(_f => t)) as Bool;
|
||||
|
||||
export const False: Bool
|
||||
= _(_ => f => f);
|
||||
= _(_t => _(f => f));
|
||||
|
||||
export const iif: <T extends V>(b: Bool) => (t: T) => (f: T) => T
|
||||
= b => t => f => b.then(b => b(t)(f));
|
||||
export const iif: <T extends V>(b: Bool) => Lazy<(t: T) => Lazy<(f: T) => T>>
|
||||
= b => _(t => _(f => b.then(b => b(t).then(e=>e(f)))));
|
||||
|
||||
export const not: (b: Bool) => Bool
|
||||
= b => b.then(b => b(False)(True));
|
||||
= b => b.then(b => b(False).then(e=>e(True)));
|
||||
|
||||
export const and: (l: Bool) => (r: Bool) => Bool
|
||||
= l => r => l.then(l => l(r)(False));
|
||||
export const and: (l: Bool) => Lazy<(r: Bool) => Bool>
|
||||
= l => _(r => l.then(l => l(r).then(e=>e(False))));
|
||||
|
||||
export const or: (l: Bool) => (r: Bool) => Bool
|
||||
= l => r => l.then(l => l(True)(r));
|
||||
export const or: (l: Bool) => Lazy<(r: Bool) => Bool>
|
||||
= l => _(r => l.then(l => l(True).then(e=>e(r))));
|
||||
|
||||
export const xor: (l: Bool) => (r: Bool) => Bool
|
||||
= l => r => l.then(l => l(not(r))(r));
|
||||
export const xor: (l: Bool) => Lazy<(r: Bool) => Bool>
|
||||
= l => _(r => l.then(l => l(not(r)).then(e=>e(r))));
|
||||
|
||||
export const fromBoolean: (b: boolean) => Bool
|
||||
= b => b ? True : False;
|
||||
|
||||
export const toBoolean: (b: Bool) => boolean
|
||||
= b => b.then(b => b(_(true))(_(false))).value;
|
||||
= b => b.then(b => b(_(true as unknown as Q)).then(e=>e(_(false as unknown as Q)))).value as unknown as boolean;
|
||||
|
||||
+8
-6
@@ -1,4 +1,4 @@
|
||||
export class Lazy<T> {
|
||||
export class Lazy<T extends (v: unknown) => Lazy<any>> {
|
||||
protected _value?: T;
|
||||
|
||||
constructor(private _eval: () => T) { }
|
||||
@@ -18,10 +18,12 @@ export class Lazy<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export type V = Lazy<unknown>;
|
||||
export type Q = (v: unknown) => Lazy<any>;
|
||||
|
||||
export const _ = <T>(v: T): Lazy<T> => new Lazy(() => v);
|
||||
export const $ = <T>(v: Lazy<T>): T => v.value;
|
||||
export type V = Lazy<(v: unknown) => Lazy<any>>;
|
||||
|
||||
export const _ = <T extends (v: unknown) => Lazy<any>>(v: T): Lazy<T> => new Lazy(() => v);
|
||||
export const $ = <T extends (v: unknown) => Lazy<any>>(v: Lazy<T>): T => v.value;
|
||||
|
||||
export const undef: any = new Lazy(() => {
|
||||
throw new Error('undefined');
|
||||
@@ -29,5 +31,5 @@ export const undef: any = new Lazy(() => {
|
||||
|
||||
export const id: <T extends V>(v: T) => T
|
||||
= v => v;
|
||||
export const cnst: <T extends V> (v: T) => (_: unknown) => T
|
||||
= v => _ => v;
|
||||
export const cnst: <T extends V> (v: T) => Lazy<(_: unknown) => T>
|
||||
= v => _(_ => v);
|
||||
|
||||
+25
-25
@@ -1,50 +1,50 @@
|
||||
import { Lazy, V, _, cnst, id, undef } from './core';
|
||||
import { Lazy, Q, V, _, undef } from './core';
|
||||
import { fromNumber, Num, toNumber } from './num';
|
||||
import { Bool, iif } from './bool';
|
||||
|
||||
export type List<T extends V> = Lazy<<R extends V>(z: R) => (f: (x: T) => (xs: List<T>) => R) => R>;
|
||||
export type List<T extends V> = Lazy<<R extends V>(z: R) => Lazy<(f: (x: T) => Lazy<(xs: List<T>) => R>) => R>>;
|
||||
|
||||
export const Nil: List<any>
|
||||
= _(z => _ => z) as List<any>;
|
||||
= _(z => _(_f => z)) as List<any>;
|
||||
|
||||
export const Cons: <T extends V>(x: T) => (xs: List<T>) => List<T>
|
||||
= <T extends V>(x: T) => (xs: List<T>) => _(_ => f => f(x)(xs)) as List<T>;
|
||||
export const Cons: <T extends V>(x: T) => Lazy<(xs: List<T>) => List<T>>
|
||||
= <T extends V>(x: T) => _((xs: List<T>) => _(_z => _(f => f(x).then(e=>e(xs)))) as List<T>);
|
||||
|
||||
export const cons: <T extends V>(x: T) => (xs: List<T>) => List<T>
|
||||
export const cons: <T extends V>(x: T) => Lazy<(xs: List<T>) => List<T>>
|
||||
= Cons;
|
||||
|
||||
export const head: <T extends V>(xs: List<T>) => T
|
||||
= xs => xs.then(xs => xs(undef)(cnst));
|
||||
= xs => xs.then(xs => xs(undef).then(e=>e(x=>_(_xs=>x))));
|
||||
|
||||
export const tail: <T extends V>(xs: List<T>) => List<T>
|
||||
= xs => xs.then(xs => xs(undef)(_ => id));
|
||||
= xs => xs.then(xs => xs(undef).then(e=>e(_x =>_(xs=>xs))));
|
||||
|
||||
export const foldl: <T extends V, R extends V>(f: (a: R) => (x: T) => R) => (z: R) => (xs: List<T>) => R
|
||||
= f => z => xs => xs.then(xs => xs(z)(x => xs => foldl(f)(f(z)(x))(xs)));
|
||||
export const foldl: <T extends V, R extends V>(f: (a: R) => Lazy<(x: T) => R>) => Lazy<(z: R) => Lazy<(xs: List<T>) => R>>
|
||||
= f => _(z => _(xs => xs.then(xs => xs(z).then(e=>e(x => _(xs => foldl(f).then(e=>e(f(z).then(e=>e(x))).then(e=>e(xs)))))))));
|
||||
|
||||
export const foldlz: <T extends V>(f: (a: T) => (x: T) => T) => (xs: List<T>) => T
|
||||
= f => xs => xs.then(xs => xs(undef)(foldl(f)));
|
||||
export const foldlz: <T extends V>(f: (a: T) => Lazy<(x: T) => T>) => Lazy<(xs: List<T>) => T>
|
||||
= f => _(xs => xs.then(xs => xs(undef).then(e=>e(x=>_(xs=>foldl(f).then(e=>e(x).then(e=>e(xs))))))));
|
||||
|
||||
export const foldr: <T extends V, R extends V>(f: (x: T) => (a: R) => R) => (z: R) => (xs: List<T>) => R
|
||||
= f => z => xs => xs.then(xs => xs(z)(x => xs => f(x)(foldr(f)(z)(xs))));
|
||||
export const foldr: <T extends V, R extends V>(f: (x: T) => Lazy<(a: R) => R>) => Lazy<(z: R) => Lazy<(xs: List<T>) => R>>
|
||||
= f => _(z => _(xs => xs.then(xs => xs(z).then(e=>e(x => _(xs => f(x).then(e=>e(foldr(f).then(e=>e(z).then(e=>e(xs)))))))))));
|
||||
|
||||
export const foldrz: <T extends V>(f: (x: T) => (a: T) => T) => (xs: List<T>) => T
|
||||
= _ => _ => undef;
|
||||
export const foldrz: <T extends V>(f: (x: T) => Lazy<(a: T) => T>) => Lazy<(xs: List<T>) => T>
|
||||
= _f => _(_z => undef);
|
||||
|
||||
export const map: <T extends V, R extends V>(f: (x: T) => R) => (xs: List<T>) => List<R>
|
||||
= f => xs => xs.then(xs => xs(Nil)(x => xs => Cons(f(x))(map(f)(xs))));
|
||||
export const map: <T extends V, R extends V>(f: (x: T) => R) => Lazy<(xs: List<T>) => List<R>>
|
||||
= f => _(xs => xs.then(xs => xs(Nil).then(e=>e(x =>_( xs => Cons(f(x)).then(e=>e(map(f).then(e=>e(xs)))))))));
|
||||
|
||||
export const filter: <T extends V>(f: (x: T) => Bool) => (xs: List<T>) => List<T>
|
||||
= <T extends V>(f: (x: T) => Bool) => (xs: List<T>) => xs.then(xs => xs(Nil)(x => xs => iif<List<T>>(f(x))(Cons(x)(filter(f)(xs)))(filter(f)(xs))));
|
||||
export const filter: <T extends V>(f: (x: T) => Bool) => Lazy<(xs: List<T>) => List<T>>
|
||||
= <T extends V>(f: (x: T) => Bool) => _((xs: List<T>) => xs.then(xs => xs(Nil).then(e=>e(x => _(xs => iif<List<T>>(f(x)).then(e=>e(Cons(x).then(e=>e(filter(f).then(e=>e(xs))))).then(e=>e(filter(f).then(e=>e(xs))))))))));
|
||||
|
||||
export const fromArray: <T extends V>(xs: T[]) => List<T>
|
||||
= xs => xs.length === 0 ? Nil : new Lazy(() => Cons(xs[0])(fromArray(xs.slice(1))).value);
|
||||
= xs => xs.length === 0 ? Nil : new Lazy(() => Cons(xs[0]).then(e=>e(fromArray(xs.slice(1)))).value);
|
||||
|
||||
export const fromNumberArray: (xs: number[]) => List<Num>
|
||||
= xs => xs.length === 0 ? Nil : new Lazy(() => Cons(fromNumber(xs[0]))(fromNumberArray(xs.slice(1))).value);
|
||||
= xs => xs.length === 0 ? Nil : new Lazy(() => Cons(fromNumber(xs[0])).then(e=>e(fromNumberArray(xs.slice(1)))).value);
|
||||
|
||||
export const toArray: <R, T extends Lazy<R>>(xs: List<T>) => R[]
|
||||
= <R, T extends Lazy<R>>(xs: List<T>) => xs.then(xs => xs(_([] as R[]))(x => xs => _([x.value, ...toArray<R, T>(xs)]))).value;
|
||||
export const toArray: <R extends Q, T extends Lazy<R>>(xs: List<T>) => R[]
|
||||
= <R extends Q, T extends Lazy<R>>(xs: List<T>) => xs.then(xs => xs(_([] as R[] as unknown as Q)).then(e=>e(x => _(xs => _([x.value, ...toArray<R, T>(xs)] as unknown as Q))))).value as unknown as R[];
|
||||
|
||||
export const toNumberArray: (xs: List<Num>) => number[]
|
||||
= xs => xs.then(xs => xs(_([] as number[]))(x => xs => _([toNumber(x), ...toNumberArray(xs)]))).value;
|
||||
= xs => xs.then(xs => xs(_([] as number[]as unknown as Q)).then(e=>e(x => _(xs => _([toNumber(x), ...toNumberArray(xs)]as unknown as Q))))).value as unknown as number[];
|
||||
|
||||
+15
-15
@@ -1,40 +1,40 @@
|
||||
import { Bool, not, True } from './bool';
|
||||
import { Lazy, V, _, id } from './core';
|
||||
import { Lazy, Q, V, _, id } from './core';
|
||||
|
||||
export type Num = Lazy<<T extends V>(z: T) => (n: (p: Num) => T) => T>;
|
||||
export type Num = Lazy<<T extends V>(z: T) => Lazy<(n: (p: Num) => T) => T>>;
|
||||
|
||||
export const Zero: Num
|
||||
= _(z => _ => z) as Num;
|
||||
= _(z => _(_n => z)) as Num;
|
||||
|
||||
export const Succ: (p: Num) => Num
|
||||
= p => _(_ => n => n(p));
|
||||
= p => _(_z => _(n => n(p)));
|
||||
|
||||
export const ifz: <T extends V>(n: Num) => (t: T) => (f: T) => T
|
||||
= n => t => f => n.then(n => n(t)(_ => f));
|
||||
export const ifz: <T extends V>(n: Num) => Lazy<(t: T) => Lazy<(f: T) => T>>
|
||||
= n => _(t => _(f => n.then(n => n(t).then(e => e(_ => f)))));
|
||||
|
||||
export const succ: (n: Num) => Num
|
||||
= Succ;
|
||||
|
||||
export const pred: (n: Num) => Num
|
||||
= n => n.then(n => n(Zero)(id));
|
||||
= n => n.then(n => n(Zero).then(e=>e(id)));
|
||||
|
||||
export const even: (n: Num) => Bool
|
||||
= n => n.then(n => n(True)(odd));
|
||||
= n => n.then(n => n(True).then(e=>e(odd)));
|
||||
|
||||
export const odd: (n: Num) => Bool
|
||||
= n => not(even(n));
|
||||
|
||||
export const sum: (l: Num) => (r: Num) => Num
|
||||
= l => r => r.then(r => r(l)(sum(Succ(l))));
|
||||
export const sum: (l: Num) => Lazy<(r: Num) => Num>
|
||||
= l => _(r => r.then(r => r(l).then(e=>e(t=>sum(Succ(l)).then(e=>e(t))))));
|
||||
|
||||
export const sub: (l: Num) => (r: Num) => Num
|
||||
= l => r => r.then(r => r(l)(pr => l.then(l => l(Zero)(pl => sub(pl)(pr)))));
|
||||
export const sub: (l: Num) => Lazy<(r: Num) => Num>
|
||||
= l => _(r => r.then(r => r(l).then(e=>e(pr => l.then(l => l(Zero).then(e=>e(pl => sub(pl).then(e=>e(pr)))))))));
|
||||
|
||||
export const mul: (l: Num) => (r: Num) => Num
|
||||
= l => r => l.then(l => l(Zero)(pl => sum(r)(mul(pl)(r))));
|
||||
export const mul: (l: Num) => Lazy<(r: Num) => Num>
|
||||
= l => _(r => l.then(l => l(Zero).then(e=>e(pl => sum(r).then(e=>e(mul(pl).then(e=>e(r))))))));
|
||||
|
||||
export const fromNumber: (n: number) => Num
|
||||
= n => !n ? Zero : new Lazy(() => Succ(fromNumber(n - 1)).value);
|
||||
|
||||
export const toNumber: (n: Num) => number
|
||||
= n => n.then(n => n(_(0))(p => _(1 + toNumber(p)))).value;
|
||||
= n => n.then(n => n(_(0 as unknown as Q)).then(e=>e(p => _((1 + toNumber(p)) as unknown as Q)))).value as unknown as number;
|
||||
|
||||
Reference in New Issue
Block a user