export const TreeTypeId = Symbol.for("@tsplus/collections/Tree") export type TreeTypeId = typeof TreeTypeId export type Forest = Tree.Forest /** * @tsplus type Tree * @tsplus companion Tree.Ops */ export class Tree implements Equals { readonly [TreeTypeId]: TreeTypeId = TreeTypeId constructor(readonly value: A, readonly forest: Forest) {} [Equals.sym](this: this, other: unknown): boolean { return ( Tree.isTree(other) && Equals.equals(this.value, other.value) && this.forest.corresponds(other.forest, (a, b) => Equals.equals(a, b)) ) } [Hash.sym](this: this): number { return pipe(Hash.combine(Hash.unknown(this.value), this.forest[Hash.sym]()), Hash.optimize) } } export interface TreeF extends HKT { readonly type: Tree } export declare namespace Tree { export type HKT = TreeF export type Forest = Chunk> } /** * @tsplus type Tree.Aspects */ export interface TreeAspects {} /** * @tsplus static Tree.Ops $ */ export const TreeAspects: TreeAspects = {} const empty = Chunk.empty() /** * @tsplus static Tree.Ops __call */ export function make(value: A, forest: Forest = empty): Tree { return new Tree(value, forest) } /** * Type guard * * @tsplus static Tree.Ops isTree */ export function isTree(t: unknown): t is Tree { return typeof t === "object" && t instanceof Tree && TreeTypeId in t }