Pipes
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import { L, _, fromNative as __, cnst, id } from './core';
|
||||
import { L, _, fromNative as __, cnst, id, pipe } from './core';
|
||||
import { Bool, iif } from './bool';
|
||||
import { Num, Zero, ge, ifz, pred, succ } from './num';
|
||||
import { x00 } from './byte';
|
||||
import { Char, fromChar as _c, dec as cdec, inc as cinc, eq, ifn } from './char';
|
||||
import { Pair, first, fst, second, snd, uncurry } from './pair';
|
||||
import { List, Nil, cons, head, repeat, set, tail, update } from './list';
|
||||
import { List, Nil, cons, head, repeat, set, singleton, tail, update } from './list';
|
||||
import { Empty, String, get, len, snoc } from './string';
|
||||
|
||||
type Program = Pair<List<Num>, String>;
|
||||
@@ -19,12 +19,11 @@ const done: L<(s: State) => Bool>
|
||||
= uncurry(_(p => cnst(uncurry(_(is => _(cs => ge(head(is))(len(cs)))))(p))));
|
||||
|
||||
const command: L<(c: String) => L<(s: State) => Bool>>
|
||||
= _(c => uncurry(_(p => cnst(eq(c)(uncurry(_(is => get(head(is))))(p))))));
|
||||
= _(c => uncurry(_(p => cnst(eq(c)(uncurry(pipe(get)(head))(p))))));
|
||||
|
||||
const advance: L<(s: State) => State>
|
||||
= first(first(update(succ)(Zero)));
|
||||
|
||||
|
||||
const save: L<(s: State) => State>
|
||||
= first(first(_(is => cons(head(is))(is))));
|
||||
|
||||
@@ -41,13 +40,13 @@ const dec: L<(t: State) => State>
|
||||
= second(first(_(t => second(update(cdec)(fst(t)))(t))));
|
||||
|
||||
const read: L<(s: State) => Char>
|
||||
= _(s => uncurry(get)(fst(snd(s))));
|
||||
= pipe(pipe(uncurry(get))(fst))(snd);
|
||||
|
||||
const input: L<(s: State) => State>
|
||||
= second(uncurry(_(t => _(io => Pair(second(set(head(fst(io)))(fst(t)))(t))(first(tail)(io))))));
|
||||
|
||||
const output: L<(s: State) => State>
|
||||
= second(uncurry(_(t => _(io => Pair(t)(second(_(os => snoc(os)(uncurry(get)(t))))(io))))));
|
||||
= second(uncurry(_(t => pipe(Pair(t))(second(_(os => snoc(os)(uncurry(get)(t))))))));
|
||||
|
||||
const next: L<(t: State) => State>
|
||||
= second(first(first(succ)));
|
||||
@@ -65,10 +64,7 @@ const whlnz: L<(t: State) => State>
|
||||
= _(s => ifn(read(s))(jump(Zero))(save)(s));
|
||||
|
||||
const endwhl: L<(t: State) => State>
|
||||
= _(s => ifn(read(s))(reset(s))(save(restore(s))));
|
||||
|
||||
const when: L<(c: String) => L<(f: L<(s: State) => State>) => L<(s:State)=>State>>>
|
||||
= _(c => _(f => _(s => iif(command(c)(s))(f(s))(s))));
|
||||
= _(s => ifn(read(s))(reset)(pipe(save)(restore))(s));
|
||||
|
||||
const exec: L<(s: State) => State>
|
||||
= _(s => iif<State>(done(s))(s)(exec(advance
|
||||
@@ -83,4 +79,4 @@ const exec: L<(s: State) => State>
|
||||
(id))))))))(s)))));
|
||||
|
||||
export const run: L<(p: String) => L<(i: String) => String>>
|
||||
= _(p => _(i => snd(snd(snd(exec(Pair(Pair(cons(Zero)(Nil))(p))(Pair(Pair(Zero)(repeat(x00)))(Pair(i)(Empty)))))))));
|
||||
= _(p => _(i => snd(snd(snd(exec(Pair(Pair(singleton(Zero))(p))(Pair(Pair(Zero)(repeat(x00)))(Pair(i)(Empty)))))))));
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
import { toNative as $$, L, P, _, fromNative as __, id } from './core';
|
||||
import { toNative as $$, L, P, _, fromNative as __, id, pipe } from './core';
|
||||
import { EQ, GT, LT, Ord } from './ord';
|
||||
import { String, fromString as _s } from './string';
|
||||
|
||||
@@ -29,10 +29,10 @@ export const eq: L<(l: Bool) => L<(r: Bool) => Bool>>
|
||||
= _(l => _(r => l(r)(not(r))));
|
||||
|
||||
export const ge: L<(l: Bool) => L<(r: Bool) => Bool>>
|
||||
= _(l => _(r => not(lt(l)(r))));
|
||||
= _(l => pipe(not)(lt(l)));
|
||||
|
||||
export const gt: L<(l: Bool) => L<(r: Bool) => Bool>>
|
||||
= _(l => _(r => not(le(l)(r))));
|
||||
= _(l => pipe(not)(le(l)));
|
||||
|
||||
export const and: L<(l: Bool) => L<(r: Bool) => Bool>>
|
||||
= _(l => not(l)(False));
|
||||
|
||||
+4
-3
@@ -1,6 +1,7 @@
|
||||
import { L, _ } from './core';
|
||||
import { L, _, pipe } from './core';
|
||||
import { toNumber as $n, Byte, fromNumber as _n, x00 } from './byte';
|
||||
import { Empty, String, cons, fromString as _s, wrap } from './string';
|
||||
import { singleton } from './list';
|
||||
import { String, fromString as _s, wrap } from './string';
|
||||
|
||||
export type Char = Byte;
|
||||
|
||||
@@ -10,7 +11,7 @@ export const Null: Char
|
||||
export { inc, dec, ifz as ifn, cmp, lt, le, eq, ge, gt } from './byte';
|
||||
|
||||
export const show: L<(c: Char) => String>
|
||||
= _(c => wrap(_s('\''))(cons(c)(Empty)));
|
||||
= _(c => pipe(wrap(_s('\'')))(singleton)(c));
|
||||
|
||||
export const fromChar: (c: string) => Char
|
||||
= c => _n(c.charCodeAt(0));
|
||||
|
||||
@@ -30,3 +30,7 @@ export const id: L<<T extends P>(v: T) => T>
|
||||
= _(v => v);
|
||||
export const cnst: L<<T extends P>(v: T) => L<(_: unknown) => T>>
|
||||
= _(v => _(_ => v)) as L<<T extends P>(v: T) => L<(_: unknown) => T>>;
|
||||
export const pipe: L<<A extends P, B extends P, C extends P>(f: L<(v: B) => C>) => L<(g: L<(v: A) => B>) => L<(v: A) => C>>>
|
||||
= _(<A extends P, B extends P, C extends P>(f: L<(v: B) => C>) =>
|
||||
_((g: L<(v: A) => B>) =>
|
||||
_((v: A) => f(g(v)))));
|
||||
|
||||
+13
-10
@@ -1,4 +1,4 @@
|
||||
import { toNative as $$, L, P, _, fromNative as __, ___, cnst, id, undef } from './core';
|
||||
import { toNative as $$, L, P, _, fromNative as __, ___, cnst, id, pipe, undef } from './core';
|
||||
import { EQ, GT, LT, Ord, eq as eqc } from './ord';
|
||||
import { Bool, False, True, and, iif, or } from './bool';
|
||||
import { Num, Zero, succ } from './num';
|
||||
@@ -23,13 +23,16 @@ export const nul: L<<T extends P>(xs: List<T>) => Bool>
|
||||
= _(xs => xs(True)(cnst(cnst(False))));
|
||||
|
||||
export const len: L<<T extends P>(xs: List<T>) => Num>
|
||||
= _(xs => xs(Zero)(_(_x => _(xs => succ(len(xs))))));
|
||||
= _(xs => xs(Zero)(cnst(pipe(succ)(len))));
|
||||
|
||||
export const singleton: L<<T extends P>(v: T) => List<T>>
|
||||
= _(x => cons(x)(Nil));
|
||||
|
||||
export const append: L<<T extends P>(l: List<T>) => L<(r: List<T>) => List<T>>>
|
||||
= _(l => _(r => l(r)(_(x => _(xs => cons(x)(append(xs)(r)))))));
|
||||
|
||||
export const concat: L<<T extends P>(ls: List<List<T>>) => List<T>>
|
||||
= _(ls => ls(Nil)(_(x => _(xs => append(x)(concat(xs))))));
|
||||
= _(ls => ls(Nil)(_(x => pipe(append(x))(concat))));
|
||||
|
||||
export const repeat: L<<T extends P>(x: T) => List<T>>
|
||||
= _(x => cons(x)(repeat(x)));
|
||||
@@ -46,7 +49,7 @@ export const tail: L<<T extends P>(xs: List<T>) => List<T>>
|
||||
export const foldl: L<<T extends P, R extends P>(f: L<(a: R) => L<(x: T) => R>>) => L<(z: R) => L<(xs: List<T>) => R>>>
|
||||
= _(<T extends P, R extends P>(f: L<(a: R) => L<(x: T) => R>>) =>
|
||||
_((z: R) =>
|
||||
_((xs: List<T>) => xs(z)(_(x => foldl(f)(f(z)(x)))))));
|
||||
_((xs: List<T>) => xs(z)(pipe(foldl(f))(f(z))))));
|
||||
|
||||
export const foldlz: L<<T extends P>(f: L<(a: T) => L<(x: T) => T>>) => L<(xs: List<T>) => T>>
|
||||
= _(<T extends P>(f: L<(a: T) => L<(x: T) => T>>) => _((xs: List<T>) => xs(undef)(foldl(f))));
|
||||
@@ -54,7 +57,7 @@ export const foldlz: L<<T extends P>(f: L<(a: T) => L<(x: T) => T>>) => L<(xs: L
|
||||
export const foldr: L<<T extends P, R extends P>(f: L<(x: T) => L<(a: R) => R>>) => L<(z: R) => L<(xs: List<T>) => R>>>
|
||||
= _(<T extends P, R extends P>(f: L<(x: T) => L<(a: R) => R>>) =>
|
||||
_((z: R) =>
|
||||
_((xs: List<T>) => xs(z)(_(x => _(xs => f(x)(foldr(f)(z)(xs))))))));
|
||||
_((xs: List<T>) => xs(z)(_(x => pipe(f(x))(foldr(f)(z)))))));
|
||||
|
||||
export const foldrz: L<<T extends P>(f: L<(x: T) => L<(a: T) => T>>) => L<(xs: List<T>) => T>>
|
||||
= undef;
|
||||
@@ -102,19 +105,19 @@ export const gt: L<<T extends P>(ecmp: L<(l: T) => L <(r: T) => Ord>>) => L<(l:
|
||||
|
||||
export const map: L<<T extends P, R extends P>(f: L<(x: T) => R>) => L<(xs: List<T>) => List<R>>>
|
||||
= _(<T extends P, R extends P>(f: L<(x: T) => R>) =>
|
||||
_((xs: List<T>) => xs(Nil)(_(x => _(xs => cons(f(x))(map(f)(xs)))))));
|
||||
_((xs: List<T>) => xs(Nil)(_(x => pipe(cons(f(x)))(map(f))))));
|
||||
|
||||
export const filter: L<<T extends P>(f: L<(x: T) => Bool>) => L<(xs: List<T>) => List<T>>>
|
||||
= _(<T extends P>(f: L<(x: T) => Bool>) =>
|
||||
_((xs: List<T>) => xs(Nil)(_(x => _(xs => iif(f(x))(cons(x))(id)(filter(f)(xs)))))));
|
||||
_((xs: List<T>) => xs(Nil)(_(x => pipe(iif(f(x))(cons(x))(id))(filter(f))))));
|
||||
|
||||
export const any: L<<T extends P>(f: L<(x: T) => Bool>) => L<(xs: List<T>) => Bool>>
|
||||
= _(<T extends P>(f: L<(x: T) => Bool>) =>
|
||||
_((xs: List<T>) => xs(False)(_(x => _(xs => or(f(x))(any(f)(xs)))))));
|
||||
_((xs: List<T>) => xs(False)(_(x => pipe(or(f(x)))(any(f))))));
|
||||
|
||||
export const all: L<<T extends P>(f: L<(x: T) => Bool>) => L<(xs: List<T>) => Bool>>
|
||||
= _(<T extends P>(f: L<(x: T) => Bool>) =>
|
||||
_((xs: List<T>) => xs(True)(_(x => _(xs => and(f(x))(all(f)(xs)))))));
|
||||
_((xs: List<T>) => xs(True)(_(x => pipe(and(f(x)))(all(f))))));
|
||||
|
||||
export const get: L<<T extends P>(i: Num) => L<(xs: List<T>) => T>>
|
||||
= _(i => _(xs => xs(undef)(_(x => i(cnst(x))(get)))));
|
||||
@@ -126,7 +129,7 @@ export const update: L<<T extends P>(f: L< (p: T) => T>) => L<(i: Num) => L<(xs:
|
||||
xs(undef)(_(x => _(xs => i(cons(f(x))(xs))(_(pi => cons(x)(update(f)(pi)(xs))))))))));
|
||||
|
||||
export const set: L<<T extends P>(v: T) => L<(i: Num) => L<(xs: List<T>) => List<T>>>>
|
||||
= _(v => update(cnst(v)));
|
||||
= pipe(update)(cnst);
|
||||
|
||||
export const intersperse: L<<T extends P>(v: T) => L<(xs: List<T>) => List<T>>>
|
||||
= _(v => _(xs => xs(xs)(_(x => _(rxs => rxs(xs)(cnst(cnst(cons(x)(cons(v)(intersperse(v)(rxs)))))))))));
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
import { toNative as $$, L, P, _, fromNative as __, ___, cnst, id } from './core';
|
||||
import { toNative as $$, L, P, _, fromNative as __, ___, cnst, id, pipe } from './core';
|
||||
import { EQ, GT, LT, Ord } from './ord';
|
||||
import { Bool, False, True, iif } from './bool';
|
||||
import { Empty, String, append, cons } from './string';
|
||||
@@ -21,7 +21,7 @@ export const pred: L<(n: Num) => Num>
|
||||
= _(n => n(Zero)(id));
|
||||
|
||||
export const cmp: L<(l: Num) => L<(r: Num) => Ord>>
|
||||
= _(l => _(r => l(r(EQ)(cnst(LT)))(_(pl => r(GT)(cmp(pl))))));
|
||||
= _(l => _(r => l(r(EQ)(cnst(LT)))(pipe(r(GT))(cmp))));
|
||||
|
||||
export const lt: L<(l: Num) => L<(r: Num) => Bool>>
|
||||
= _(l => _(r => r(False)(l(cnst(True))(lt))));
|
||||
|
||||
@@ -16,3 +16,9 @@ describe('cnst', () => {
|
||||
expect($$(cnst(__('first'))(undef))).toBe('first');
|
||||
});
|
||||
});
|
||||
|
||||
describe('pipe', () => {
|
||||
it.failing('applies both functions in order', () => {
|
||||
expect('Not implemented').toBe('Implemented');
|
||||
});
|
||||
});
|
||||
|
||||
+11
-1
@@ -4,7 +4,7 @@ import { toNOrd as $o, NOrd } from '../src/ord';
|
||||
import { toBoolean as $b, iif } from '../src/bool';
|
||||
import { toNumber as $n, toNumber as $nn, Num, Succ, Zero, fromNumber as _n, fromNumber as _nn, cmp as cmpn, eq as eqn, even, gt as ngt, show as nshow, odd, succ, sum } from '../src/num';
|
||||
import { toChar as $c } from '../src/char';
|
||||
import { toArray as $a, Cons, List, Nil, fromArray as _a, all, any, append, cmp, concat, cons, eq, filter, foldl, foldlz, foldr, foldrz, ge, get, gt, head, intersperse, iterate, le, len, lt, map, nul, set, show, snoc, tail, update } from '../src/list';
|
||||
import { toArray as $a, Cons, List, Nil, fromArray as _a, all, any, append, cmp, concat, cons, eq, filter, foldl, foldlz, foldr, foldrz, ge, get, gt, head, intersperse, iterate, le, len, lt, map, nul, set, show, singleton, snoc, tail, update } from '../src/list';
|
||||
import { toString as $s } from '../src/string';
|
||||
|
||||
describe('List', () => {
|
||||
@@ -114,6 +114,16 @@ describe('List', () => {
|
||||
it('handles infinite lists', () => {
|
||||
expect($b(ngt(len(infinite))(Zero))).toEqual(true);
|
||||
});
|
||||
|
||||
it('ignores items', () => {
|
||||
expect($n(len(cons(undef)(cons(undef)(Nil))))).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('singleton', () => {
|
||||
it('singleton 0 is [0]', () => {
|
||||
expect($na(singleton(_n(0)))).toEqual([0]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('append', () => {
|
||||
|
||||
Reference in New Issue
Block a user