Skip to content

Instantly share code, notes, and snippets.

@pelotom
Last active May 18, 2022 10:08
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pelotom/62aaadac9a12b424a49e2db6341d6903 to your computer and use it in GitHub Desktop.
Save pelotom/62aaadac9a12b424a49e2db6341d6903 to your computer and use it in GitHub Desktop.
Encoding of existential types in TypeScript
type StackOps<S, A> = {
init(): S
push(s: S, x: A): void
pop(s: S): A
size(s: S): number
}
type Stack<A> = <R>(go: <S>(ops: StackOps<S, A>) => R) => R
const arrayStack = <A>(): Stack<A> =>
go => go<A[]>({
init: () => [],
push: (s, x) => s.push(x),
pop: s => { if (s.length) return s.pop()!; else throw Error('empty stack!'); },
size: s => s.length,
})
const doStackStuff = (stack: Stack<string>) =>
stack(({ init, push, pop, size }) => {
const s = init()
push(s, 'hello')
push(s, 'world')
push(s, 'omg')
pop(s)
return size(s)
})
expect(doStackStuff(arrayStack())).toBe(2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment