From e7010aaeb0477b3e0468ce2ce11ac4b1c7367605 Mon Sep 17 00:00:00 2001 From: Freywar Ulvnaudgari Date: Fri, 23 Aug 2024 21:54:48 +0300 Subject: [PATCH] Lazy lambda creation --- src/bf.ts | 10 +++++----- src/byte.ts | 8 ++++---- src/core.ts | 41 ++++++++++++++++++++++++++--------------- src/list.ts | 44 ++++++++++++++++++++++---------------------- src/num.show.ts | 4 ++-- src/num.ts | 26 +++++++++++++------------- src/ord.ts | 9 +++++---- test/list.spec.ts | 4 ++-- test/num.spec.ts | 4 ++-- test/string.spec.ts | 4 ++-- 10 files changed, 83 insertions(+), 71 deletions(-) diff --git a/src/bf.ts b/src/bf.ts index 6a89abf..cc147b9 100644 --- a/src/bf.ts +++ b/src/bf.ts @@ -1,4 +1,4 @@ -import { _, _l, cnst, g, id, n, pipe, _r } from './core'; +import { _, _l, cnst, g, id, n, pipe } from './core'; import { iif } from './bool'; import { Zero, ge, ifz, pred, succ } from './num'; import { x00 } from './byte'; @@ -36,15 +36,15 @@ const next = g('next', second._(first._(first._(succ)))); const prev = g('prev', second._(first._(first._(pred)))); const jump = g('jump', _l(d => _l(s => - iif._(command._(_c('['))._(s))._(_r('bf', 'jump')._(succ._(d))) - ._(iif._(command._(_c(']'))._(s))._(ifz._(pred._(d))._(cnst._(s))._(_r('bf', 'jump')._(pred._(d)))) - ._(_r('bf', 'jump')._(d)))._(advance._(s))))); + iif._(command._(_c('['))._(s))._(jump._(succ._(d))) + ._(iif._(command._(_c(']'))._(s))._(ifz._(pred._(d))._(cnst._(s))._(jump._(pred._(d)))) + ._(jump._(d)))._(advance._(s))))); const whlnz = g('whlnz', _l(s => ifn._(read._(s))._(jump._(Zero))._(save)._(s))); const endwhl = g('endwhl', _l(s => ifn._(read._(s))._(reset)._(pipe._(save)._(restore))._(s))); -const exec = g('exec', _l(s => iif._(done._(s))._(s)._(_r('bf', 'exec')._(advance +const exec = g('exec', _l(s => iif._(done._(s))._(s)._(exec._(advance ._(iif._(command._(_c('>'))._(s))._(next) ._(iif._(command._(_c('<'))._(s))._(prev) ._(iif._(command._(_c('+'))._(s))._(inc) diff --git a/src/byte.ts b/src/byte.ts index ebe2838..3249187 100644 --- a/src/byte.ts +++ b/src/byte.ts @@ -1,4 +1,4 @@ -import { Term, _, _l, g, id, n, _r as ref } from './core'; +import { Term, _, _l, g, id, n } from './core'; import { iif } from './bool'; import { Succ, Zero, fromNumber as _n, eq } from './num'; @@ -16,10 +16,10 @@ export const inc = g('inc', Inc); export const dec = g('dec', _l(n => n._(xFF)._(id))); -export const sum = g('sum', _l(l => _l(r => r._(l)._(ref('byte', 'sum')._(inc._(l)))))); +export const sum = g('sum', _l(l => _l(r => r._(l)._(sum._(inc._(l)))))); -export const sub = g('sub', _l(l => _l(r => r._(l)._(ref('byte', 'sub')._(dec._(l)))))); +export const sub = g('sub', _l(l => _l(r => r._(l)._(sub._(dec._(l)))))); -export const mul = g('mul', _l(l => _l(r => l._(x00)._(_l(pl => sum._(r)._(ref('byte', 'mul')._(pl)._(r))))))); +export const mul = g('mul', _l(l => _l(r => l._(x00)._(_l(pl => sum._(r)._(mul._(pl)._(r))))))); export const fromNumber: (n: number) => Term = n => _n(n % 256); diff --git a/src/core.ts b/src/core.ts index 819a5b6..fd3f979 100644 --- a/src/core.ts +++ b/src/core.ts @@ -63,15 +63,6 @@ export abstract class Term { } } -type Termify = { - (term: Term): Term - (name: string): Term - (namespace: string, name: string): Term -}; - -const termify: Termify = (termOrNameOrNamespace: Term | string, maybeName?: string) => - typeof termOrNameOrNamespace === 'string' ? _r(termOrNameOrNamespace as string, maybeName as string) : termOrNameOrNamespace; - export class Undef extends Term { constructor() { super(); } @@ -178,10 +169,32 @@ export class Ref extends Term { } export class Lambda extends Term { + public constructor(resolve: (p: Ref) => Term); + public constructor(param: string, body: Term); public constructor( - public param: string, - public body: Term, - ) { super(); } + resolveOrParam: ((p: Ref) => Term) | string, + maybeBody?: Term, + ) { + super(); + this._resolve = typeof resolveOrParam === 'function' ? resolveOrParam : () => new Undef(); + this._param = typeof resolveOrParam === 'string' ? resolveOrParam : null; + this._body = maybeBody ?? null; + } + + private _resolve: (p: Ref) => Term; + public get resolve(): (p: Ref) => Term { + return this._resolve; + } + + private _param: string | null = null; + public get param(): string { + return this._param ??= this.resolve.toString().split(' ')[0]; + } + + private _body: Term | null = null; + public get body(): Term { + return this._body ??= this.resolve(new Ref('local', this.param)); + } public override refs(name: string): boolean { return this.param !== name && this.body.refs(name); @@ -281,9 +294,7 @@ export const g = (name: string, term: Term) => { return new Ref(namespace, name); }; -export const _r = (ns: string, name: string) => new Ref(ns, name); - -export const _l = (f: (p: Ref) => Term) => new Lambda(f.toString().split(' ')[0], f(new Ref('local', f.toString().split(' ')[0]))); +export const _l = (f: (p: Ref) => Term) => new Lambda(f); type Deferedify = { (value: (bindings: Record) => Term): Deferred diff --git a/src/list.ts b/src/list.ts index e919403..9d9a3a1 100644 --- a/src/list.ts +++ b/src/list.ts @@ -1,4 +1,4 @@ -import { $, Term, _, _l, cnst, g, id, n, pipe, _r as ref, undef } from './core'; +import { $, Term, _, _l, cnst, g, id, n, pipe, undef } from './core'; import { EQ, GT, LT, eq as eqc } from './ord'; import { False, True, and, iif, or } from './bool'; import { Zero, succ } from './num'; @@ -11,61 +11,61 @@ export const Cons = g('Cons', _l(x => _l(xs => _l(_ => _l(f => f._(x)._(xs)))))) export const cons = g('cons', Cons); -export const snoc = g('snoc', _l(xs => _l(x => xs._(cons._(x)._(Nil))._(_l(y => _l(ys => cons._(y)._(ref('list', 'snoc')._(ys)._(x)))))))); +export const snoc = g('snoc', _l(xs => _l(x => xs._(cons._(x)._(Nil))._(_l(y => _l(ys => cons._(y)._(snoc._(ys)._(x)))))))); export const nul = g('nul', _l(xs => xs._(True)._(cnst._(cnst._(False))))); -export const len = g('len', _l(xs => xs._(Zero)._(cnst._(pipe._(succ)._(ref('list', 'len')))))); +export const len = g('len', _l(xs => xs._(Zero)._(cnst._(pipe._(succ)._(len))))); export const singleton = g('singleton', _l(x => cons._(x)._(Nil))); -export const append = g('append', _l(l => _l(r => l._(r)._(_l(x => _l(xs => cons._(x)._(ref('list', 'append')._(xs)._(r)))))))); +export const append = g('append', _l(l => _l(r => l._(r)._(_l(x => _l(xs => cons._(x)._(append._(xs)._(r)))))))); -export const concat = g('concat', _l(ls => ls._(Nil)._(_l(x => pipe._(append._(x))._(ref('list', 'concat')))))); +export const concat = g('concat', _l(ls => ls._(Nil)._(_l(x => pipe._(append._(x))._(concat))))); -export const repeat = g('repeat', _l(x => cons._(x)._(ref('list', 'repeat')._(x)))); +export const repeat = g('repeat', _l(x => cons._(x)._(repeat._(x)))); -export const iterate = g('iterate', _l(f => _l(x => cons._(x)._(ref('list', 'iterate')._(f)._(f._(x)))))); +export const iterate = g('iterate', _l(f => _l(x => cons._(x)._(iterate._(f)._(f._(x)))))); export const head = g('head', _l(xs => xs._(undef)._(cnst))); export const tail = g('tail', _l(xs => xs._(undef)._(cnst._(id)))); -export const foldl = g('foldl', _l(f => _l(z => _l(xs => xs._(z)._(pipe._(ref('list', 'foldl')._(f))._(f._(z))))))); +export const foldl = g('foldl', _l(f => _l(z => _l(xs => xs._(z)._(pipe._(foldl._(f))._(f._(z))))))); export const foldlz = g('foldlz', _l(f => _l(xs => xs._(undef)._(foldl._(f))))); -export const foldr = g('foldr', _l(f => _l(z => _l(xs => xs._(z)._(_l(x => pipe._(f._(x))._(ref('list', 'foldr')._(f)._(z)))))))); +export const foldr = g('foldr', _l(f => _l(z => _l(xs => xs._(z)._(_l(x => pipe._(f._(x))._(foldr._(f)._(z)))))))); export const foldrz = g('foldrz', undef); -export const cmp = g('cmp', _l(ecmp => _l(l => _l(r => l._(r._(EQ)._(cnst._(cnst._(LT))))._(_l(lx => _l(lxs => r._(GT)._(_l(rx => _l(rxs => iif._(eqc._(EQ)._(ecmp._(lx)._(rx)))._(ref('list', 'cmp')._(ecmp)._(lxs)._(rxs))._(ecmp._(lx)._(rx)))))))))))); +export const cmp = g('cmp', _l(ecmp => _l(l => _l(r => l._(r._(EQ)._(cnst._(cnst._(LT))))._(_l(lx => _l(lxs => r._(GT)._(_l(rx => _l(rxs => iif._(eqc._(EQ)._(ecmp._(lx)._(rx)))._(cmp._(ecmp)._(lxs)._(rxs))._(ecmp._(lx)._(rx)))))))))))); -export const lt = g('lt', _l(ecmp => _l(l => _l(r => r._(False)._(_l(rx => _l(rxs => l._(True)._(_l(lx => _l(lxs => ecmp._(lx)._(rx)._(True)._(ref('list', 'lt')._(ecmp)._(lxs)._(rxs))._(False))))))))))); +export const lt = g('lt', _l(ecmp => _l(l => _l(r => r._(False)._(_l(rx => _l(rxs => l._(True)._(_l(lx => _l(lxs => ecmp._(lx)._(rx)._(True)._(lt._(ecmp)._(lxs)._(rxs))._(False))))))))))); -export const le = g('le', _l(ecmp => _l(l => _l(r => l._(True)._(_l(lx => _l(lxs => r._(False)._(_l(rx => _l(rxs => ecmp._(lx)._(rx)._(True)._(ref('list', 'le')._(ecmp)._(lxs)._(rxs))._(False))))))))))); +export const le = g('le', _l(ecmp => _l(l => _l(r => l._(True)._(_l(lx => _l(lxs => r._(False)._(_l(rx => _l(rxs => ecmp._(lx)._(rx)._(True)._(le._(ecmp)._(lxs)._(rxs))._(False))))))))))); -export const eq = g('eq', _l(eeq => _l(l => _l(r => l._(r._(True)._(cnst._(cnst._(False))))._(_l(lx => _l(lxs => r._(False)._(_l(rx => _l(rxs => and._(eeq._(lx)._(rx))._(ref('list', 'eq')._(eeq)._(lxs)._(rxs)))))))))))); +export const eq = g('eq', _l(eeq => _l(l => _l(r => l._(r._(True)._(cnst._(cnst._(False))))._(_l(lx => _l(lxs => r._(False)._(_l(rx => _l(rxs => and._(eeq._(lx)._(rx))._(eq._(eeq)._(lxs)._(rxs)))))))))))); -export const ge = g('ge', _l(ecmp => _l(l => _l(r => r._(True)._(_l(rx => _l(rxs => l._(False)._(_l(lx => _l(lxs => ecmp._(lx)._(rx)._(False)._(ref('list', 'ge')._(ecmp)._(lxs)._(rxs))._(True))))))))))); +export const ge = g('ge', _l(ecmp => _l(l => _l(r => r._(True)._(_l(rx => _l(rxs => l._(False)._(_l(lx => _l(lxs => ecmp._(lx)._(rx)._(False)._(ge._(ecmp)._(lxs)._(rxs))._(True))))))))))); -export const gt = g('gt', _l(ecmp => _l(l => _l(r => l._(False)._(_l(lx => _l(lxs => r._(True)._(_l(rx => _l(rxs => ecmp._(lx)._(rx)._(False)._(ref('list', 'gt')._(ecmp)._(lxs)._(rxs))._(True))))))))))); +export const gt = g('gt', _l(ecmp => _l(l => _l(r => l._(False)._(_l(lx => _l(lxs => r._(True)._(_l(rx => _l(rxs => ecmp._(lx)._(rx)._(False)._(gt._(ecmp)._(lxs)._(rxs))._(True))))))))))); -export const map = g('map', _l(f => _l(xs => xs._(Nil)._(_l(x => pipe._(cons._(f._(x)))._(ref('list', 'map')._(f))))))); +export const map = g('map', _l(f => _l(xs => xs._(Nil)._(_l(x => pipe._(cons._(f._(x)))._(map._(f))))))); -export const filter = g('filter', _l(f => _l(xs => xs._(Nil)._(_l(x => pipe._(iif._(f._(x))._(cons._(x))._(id))._(ref('list', 'filter')._(f))))))); +export const filter = g('filter', _l(f => _l(xs => xs._(Nil)._(_l(x => pipe._(iif._(f._(x))._(cons._(x))._(id))._(filter._(f))))))); -export const any = g('any', _l(f => _l(xs => xs._(False)._(_l(x => pipe._(or._(f._(x)))._(ref('list', 'any')._(f))))))); +export const any = g('any', _l(f => _l(xs => xs._(False)._(_l(x => pipe._(or._(f._(x)))._(any._(f))))))); -export const all = g('all', _l(f => _l(xs => xs._(True)._(_l(x => pipe._(and._(f._(x)))._(ref('list', 'all')._(f))))))); +export const all = g('all', _l(f => _l(xs => xs._(True)._(_l(x => pipe._(and._(f._(x)))._(all._(f))))))); -export const get = g('get', _l(i => _l(xs => xs._(undef)._(_l(x => i._(cnst._(x))._(ref('list', 'get'))))))); +export const get = g('get', _l(i => _l(xs => xs._(undef)._(_l(x => i._(cnst._(x))._(get)))))); -export const update = g('update', _l(f => _l(i => _l(xs => xs._(undef)._(_l(x => _l(xs => i._(cons._(f._(x))._(xs))._(_l(pi => cons._(x)._(ref('list', 'update')._(f)._(pi)._(xs))))))))))); +export const update = g('update', _l(f => _l(i => _l(xs => xs._(undef)._(_l(x => _l(xs => i._(cons._(f._(x))._(xs))._(_l(pi => cons._(x)._(update._(f)._(pi)._(xs))))))))))); export const set = g('set', pipe._(update)._(cnst)); -export const intersperse = g('intersperse', _l(v => _l(xs => xs._(xs)._(_l(x => _l(rxs => rxs._(xs)._(cnst._(cnst._(cons._(x)._(cons._(v)._(ref('list', 'intersperse')._(v)._(rxs)))))))))))); +export const intersperse = g('intersperse', _l(v => _l(xs => xs._(xs)._(_l(x => _l(rxs => rxs._(xs)._(cnst._(cnst._(cons._(x)._(cons._(v)._(intersperse._(v)._(rxs)))))))))))); export const fromArray: (xs: Term[]) => Term = xs => !xs.length ? Nil : Cons._(xs[0])._(_(() => fromArray(xs.slice(1)))); diff --git a/src/num.show.ts b/src/num.show.ts index c7faa04..8ca8417 100644 --- a/src/num.show.ts +++ b/src/num.show.ts @@ -1,8 +1,8 @@ -import { _, _l, g, n, _r } from './core'; +import { _, _l, g, n } from './core'; import { iif } from './bool'; import { fromNumber as _n, div, lt, mod, sum } from './num'; import { Empty, append, cons } from './string'; n('num.show'); -export const show = g('show', _l(n => iif._(lt._(n)._(_n(10)))._(cons._(sum._(n)._(_n(48)))._(Empty))._(append._(_r('num.show', 'show')._(div._(n)._(_n(10))))._(_r('num.show', 'show')._(mod._(n)._(_n(10))))))); +export const show = g('show', _l(n => iif._(lt._(n)._(_n(10)))._(cons._(sum._(n)._(_n(48)))._(Empty))._(append._(show._(div._(n)._(_n(10))))._(show._(mod._(n)._(_n(10))))))); diff --git a/src/num.ts b/src/num.ts index 3aa3674..7769933 100644 --- a/src/num.ts +++ b/src/num.ts @@ -1,4 +1,4 @@ -import { $, Term, _, _l, cnst, g, id, n, pipe, _r as ref } from './core'; +import { $, Term, _, _l, cnst, g, id, n, pipe } from './core'; import { EQ, GT, LT } from './ord'; import { False, True, iif } from './bool'; @@ -14,31 +14,31 @@ export const succ = g('succ', Succ); export const pred = g('pred', _l(n => n._(Zero)._(id))); -export const cmp = g('cmp', _l(l => _l(r => l._(r._(EQ)._(cnst._(LT)))._(pipe._(r._(GT))._(ref('num', 'cmp')))))); +export const cmp = g('cmp', _l(l => _l(r => l._(r._(EQ)._(cnst._(LT)))._(pipe._(r._(GT))._(cmp))))); -export const lt = g('lt', _l(l => _l(r => r._(False)._(l._(cnst._(True))._(ref('num', 'lt')))))); +export const lt = g('lt', _l(l => _l(r => r._(False)._(l._(cnst._(True))._(lt))))); -export const le = g('le', _l(l => _l(r => l._(True)._(r._(cnst._(False))._(ref('num', 'ge')))))); +export const le = g('le', _l(l => _l(r => l._(True)._(r._(cnst._(False))._(ge))))); -export const eq = g('eq', _l(l => _l(r => l._(r._(True)._(cnst._(False)))._(r._(cnst._(False))._(ref('num', 'eq')))))); +export const eq = g('eq', _l(l => _l(r => l._(r._(True)._(cnst._(False)))._(r._(cnst._(False))._(eq))))); -export const ge = g('ge', _l(l => _l(r => r._(True)._(l._(cnst._(False))._(ref('num', 'ge')))))); +export const ge = g('ge', _l(l => _l(r => r._(True)._(l._(cnst._(False))._(ge))))); export const gt = g('gt', _l(l => _l(r => l._(False)._(r._(cnst._(True))._(lt))))); -export const even = g('even', _l(n => n._(True)._(ref('num', 'odd')))); +export const even = g('even', _l(n => n._(True)._(odd))); -export const odd = g('odd', _l(n => n._(False)._(ref('num', 'even')))); +export const odd = g('odd', _l(n => n._(False)._(even))); -export const sum = g('sum', _l(l => _l(r => r._(l)._(ref('num', 'sum')._(Succ._(l)))))); +export const sum = g('sum', _l(l => _l(r => r._(l)._(sum._(Succ._(l)))))); -export const sub = g('sub', _l(l => _l(r => r._(l)._(l._(cnst._(Zero))._(ref('num', 'sub')))))); +export const sub = g('sub', _l(l => _l(r => r._(l)._(l._(cnst._(Zero))._(sub))))); -export const mul = g('mul', _l(l => _l(r => l._(Zero)._(_l(pl => sum._(r)._(ref('num', 'mul')._(pl)._(r))))))); +export const mul = g('mul', _l(l => _l(r => l._(Zero)._(_l(pl => sum._(r)._(mul._(pl)._(r))))))); -export const div = g('div', _l(l => _l(r => iif._(lt._(l)._(r))._(Zero)._(succ._(ref('num', 'div')._(sub._(l)._(r))._(r)))))); +export const div = g('div', _l(l => _l(r => iif._(lt._(l)._(r))._(Zero)._(succ._(div._(sub._(l)._(r))._(r)))))); -export const mod = g('mod', _l(l => _l(r => iif._(lt._(l)._(r))._(l)._(ref('num', 'mod')._(sub._(l)._(r))._(r))))); +export const mod = g('mod', _l(l => _l(r => iif._(lt._(l)._(r))._(l)._(mod._(sub._(l)._(r))._(r))))); export const fromNumber: (n: number) => Term = n => !n ? Zero : Succ._(_(() => fromNumber(n - 1))); diff --git a/src/ord.ts b/src/ord.ts index d5aaab4..07d2a32 100644 --- a/src/ord.ts +++ b/src/ord.ts @@ -1,4 +1,5 @@ -import { $, Term, _, _l, g, n, _r as ref } from './core'; +import { $, Term, _, _l, g, n } from './core'; +import { False, True } from './bool'; n('ord'); @@ -15,9 +16,9 @@ export const EQ = g('EQ', _l(_ => _l(eq => _l(_ => eq)))); export const GT = g('GT', _l(_ => _l(_ => _l(gt => gt)))); export const eq = g('eq', _l(l => _l(r => l - ._(r._(ref('bool', 'True'))._(ref('bool', 'False'))._(ref('bool', 'False'))) - ._(r._(ref('bool', 'False'))._(ref('bool', 'True'))._(ref('bool', 'False'))) - ._(r._(ref('bool', 'False'))._(ref('bool', 'False'))._(ref('bool', 'True')))))); + ._(r._(True)._(False)._(False)) + ._(r._(False)._(True)._(False)) + ._(r._(False)._(False)._(True))))); export const fromNOrd: (o: NOrd) => Term = o => o === NOrd.LT ? LT : o === NOrd.EQ ? EQ : GT; diff --git a/test/list.spec.ts b/test/list.spec.ts index 8c1a7f1..5374bc4 100644 --- a/test/list.spec.ts +++ b/test/list.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from '@jest/globals'; -import { $, Term, _, _l, g, n, undef, _r as ref } from '../src/core'; +import { $, Term, _, _l, g, n, undef } from '../src/core'; import { toNOrd as $o, NOrd } from '../src/ord'; import { toBoolean as $b, iif } from '../src/bool'; import { toNumber as $n, Succ, Zero, fromNumber as _n, fromNumber as _nn, cmp as cmpn, eq as eqn, even, gt as ngt, odd, succ, sum } from '../src/num'; @@ -160,7 +160,7 @@ describe('List', () => { }); it('handles infinite lists', () => { - const dinfinite: Term = g('dinfinite', cons._(infinite)._(ref('list.spec', 'dinfinite'))); + const dinfinite: Term = g('dinfinite', _(() => cons._(infinite)._(dinfinite))); expect($n(concat._(dinfinite)._(undef)._(_l(x => _l(_ => x))))).toBe(0); }); }); diff --git a/test/num.spec.ts b/test/num.spec.ts index 9fd2d13..ca13435 100644 --- a/test/num.spec.ts +++ b/test/num.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from '@jest/globals'; -import { Term, _, g, n, _r, undef } from '../src/core'; +import { Term, _, g, n, undef } from '../src/core'; import { toNOrd as $o, NOrd } from '../src/ord'; import { toBoolean as $b, fromBoolean as _b } from '../src/bool'; import { toNumber as $n, Succ, Zero, fromNumber as _n, cmp, div, eq, ge, gt, ifz, le, lt, mod, mul, pred, sub, succ, sum } from '../src/num'; @@ -9,7 +9,7 @@ import { show } from '../src/num.show'; n('num.spec'); describe('Num', () => { - const infinity: Term = g('infinity', _(() => Succ._(_r('num.spec', 'infinity')))); + const infinity: Term = g('infinity', _(() => Succ._(infinity))); describe('toNumber', () => { it('converts 0', () => { diff --git a/test/string.spec.ts b/test/string.spec.ts index 74dceb3..f73a2e3 100644 --- a/test/string.spec.ts +++ b/test/string.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from '@jest/globals'; -import { Term, _, _l, g, n, undef, _r as ref } from '../src/core'; +import { Term, _, _l, g, n, undef } from '../src/core'; import { NOrd, toNOrd } from '../src/ord'; import { toBoolean as $b } from '../src/bool'; import { toNumber as $n, Zero, gt as ngt } from '../src/num'; @@ -10,7 +10,7 @@ import { show } from '../src/string.show'; n('string.spec'); describe('String', () => { - const infinite: Term = g('infinite', Cons._(_c('a'))._(ref('string.spec', 'infinite'))); + const infinite: Term = g('infinite', _(() => Cons._(_c('a'))._(infinite))); describe('toString', () => { it('converts ""', () => {