Created
July 6, 2023 13:18
-
-
Save serid/d655078bf2e3f3d7b524b37b084eafad to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Lazy<T> { | |
f: () => T | |
value: T | null | |
constructor(f: () => T) { | |
this.f = f | |
this.value = null | |
} | |
get(): T { | |
if (this.value === null) { | |
this.value = this.f() | |
} | |
return this.value | |
} | |
static ofValue<T>(value: T): Lazy<T> { | |
return new Lazy(() => value) | |
} | |
} | |
class LateInit<T> { | |
value: T | null | |
constructor(value?: T) { | |
if (value === undefined) | |
this.value = null | |
else | |
this.value = value | |
} | |
get(): T { | |
if (this.value === null) { | |
throw new Error("value not set yet") | |
} | |
return this.value | |
} | |
set(value: T) { | |
if (this.value !== null) { | |
throw new Error("value already set") | |
} | |
this.value = value | |
} | |
} | |
function fixpoint<T>(foo: (self: Lazy<T>) => T): Lazy<T> { | |
let lateFoo = new LateInit<Lazy<T>>() | |
lateFoo.set(new Lazy(() => foo(lateFoo.get()))) | |
return lateFoo.get() | |
} | |
function fixpoint2<A, B>( | |
f: (self1: Lazy<A>, self2: Lazy<B>) => A, | |
g: (self1: Lazy<A>, self2: Lazy<B>) => B | |
): [Lazy<A>, Lazy<B>] { | |
let lateF: LateInit<Lazy<A>> = new LateInit() | |
let lateG: LateInit<Lazy<B>> = new LateInit() | |
lateF.set(new Lazy(() => f(lateF.get(), lateG.get()))) | |
lateG.set(new Lazy(() => g(lateF.get(), lateG.get()))) | |
return [lateF.get(), lateG.get()] | |
} | |
// class List<T> { | |
// } | |
// class Cons<T> extends List<T> { | |
// head: T | |
// tail: Lazy<List<T>> | |
// constructor(head, tail) { | |
// super() | |
// this.head = head | |
// this.tail = tail | |
// } | |
// } | |
// class Nil<T> extends List<T> { | |
// } | |
// let oneTwos: Lazy<List<number>> = new Lazy( | |
// (self) => new Cons(1, Lazy.ofValue(new Cons (2, self))) | |
// ) | |
// console.log((oneTwos.get() as Cons<number>).head); | |
// console.log(((oneTwos.get() as Cons<number>).tail.get() as Cons<number>).head); | |
// console.log((((oneTwos.get() as Cons<number>).tail.get() as Cons<number>).tail.get() as Cons<number>).head); | |
type Stream<T> = [T, Lazy<Stream<T>>] | |
let oneTwos: Lazy<Stream<number>> = fixpoint( | |
(self) => [1, Lazy.ofValue([2, self])] | |
) | |
console.log(oneTwos.get()[0]) | |
console.log(oneTwos.get()[1].get()![0]) | |
console.log(oneTwos.get()[1].get()![1].get()![0]) | |
console.log() | |
let [threes, fours]: [Lazy<Stream<number>>, Lazy<Stream<number>>] = fixpoint2( | |
(self1, self2) => [3, self2], | |
(self1, self2) => [4, self1] | |
) | |
console.log(threes.get()[0]) | |
console.log(threes.get()[1].get()![0]) | |
console.log(threes.get()[1].get()![1].get()![0]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment