4 ms·
Trying out the thing, and since this is ycombinator after all: type Lazy<A> = () => A; const lazy = <A,>(f: Lazy<A>) => { let thunk: Lazy<A> = () => {
by reuben364 3y ago
Trying out the thing, and since this is ycombinator after all:
type Lazy<A> = () => A;
const lazy = <A,>(f: Lazy<A>) => {
let thunk: Lazy<A> = () => { throw null; }
thunk = () => {
const y = f();
thunk = () => y
return y;
};
return thunk;
};
const tap = <A,B>(f: Lazy<(a: Lazy<A>) => Lazy<B>>, a: Lazy<A>): Lazy<B> =>
lazy(() => f()(a)());
const ap = (f: any, a: any): any => tap<any,any>(f, a);
const y = <A,>(f : (a: Lazy<A>) => Lazy<A>): Lazy<A> => ap(((x: any) => ap(ap(f, x), x)),((x: any) => ap(ap(f,x),x)));
type Cat = {
name: string,
friend: Cat,
prefersDryFood: boolean,
foodPerWeek: number
};
export const cat = y<Cat>(self => lazy(() => ({
name: "lol",
friend: self(),
prefersDryFood: false,
foodPerWeek: 4,
})))();
Breaks typescript though. Also, the laziness won't work here.
- compressedgas 3y agoThough you need to replace: return thunk; with: return () => thunk(); Otherwise the assignment in thunk does nothing.
- reuben364 3y agoWhoops, forgot to eta expand.