diff --git a/compiler/forget/src/Utils/Stack.ts b/compiler/forget/src/Utils/Stack.ts index 68b2df059d..a53b2207fe 100644 --- a/compiler/forget/src/Utils/Stack.ts +++ b/compiler/forget/src/Utils/Stack.ts @@ -5,10 +5,24 @@ * LICENSE file in the root directory of this source tree. */ -export interface Stack { - push(value: T): Stack; +/** + * An immutable stack data structure supporting O(1) push/pop operations. + */ +export type Stack = Node | Empty; - pop(): Stack; +// Static assertion that Stack is a StackInterface +function _assertStackInterface(stack: Stack): void { + let _: StackInterface = stack; +} + +// Internal interface to enforce consistent behavior btw Node/Empty variants +// Note that we export a union rather than the interface so that it is impossible +// to create additional variants: a Stack should always be exactly a Node or Empty +// instance. +interface StackInterface { + push(value: T): StackInterface; + + pop(): StackInterface; contains(value: T): boolean; @@ -25,7 +39,7 @@ export function empty(): Stack { return EMPTY as any; } -class Node implements Stack { +class Node implements StackInterface { #value: T; #next: Stack; @@ -58,9 +72,9 @@ class Node implements Stack { } } -class Empty implements Stack { +class Empty implements StackInterface { push(value: T): Stack { - return new Node(value, this); + return new Node(value as T, this as Stack); } pop(): Stack { return this;