Skip to content

Instantly share code, notes, and snippets.

@mebubo
Last active September 2, 2018 11:21
Show Gist options
  • Select an option

  • Save mebubo/3231b176294978784e96ff5bca9d92e2 to your computer and use it in GitHub Desktop.

Select an option

Save mebubo/3231b176294978784e96ff5bca9d92e2 to your computer and use it in GitHub Desktop.
export abstract class LinkedList<A> {
abstract head(): A
abstract tail(): LinkedList<A>
abstract size(): number
abstract getN(n: number): A
abstract add(a: A): LinkedList<A>
abstract addAt(a: A, i: number): LinkedList<A>
abstract append(a: A): LinkedList<A>
abstract isEmpty(): boolean
static empty<A>(): LinkedList<A> {
return new Nil()
}
static cons<A>(head: A, tail: LinkedList<A>): LinkedList<A> {
return new Cons(head, tail)
}
static create<A>(...as: A[]): LinkedList<A> {
return as.length === 0 ? LinkedList.empty() : new Cons(as[0], LinkedList.create(...as.slice(1)))
}
}
class Nil<A> implements LinkedList<A> {
head(): never { throw new Error("head of an empty list") }
tail(): never { throw new Error("tail of an empty list") }
size(): number { return 0 }
getN(n: number): never { throw new Error("index out of bounds") }
add(a: A): LinkedList<A> { return new Cons(a, LinkedList.empty()) }
addAt(a: A, i: number): LinkedList<A> {
if (i === 0) {
return this.add(a)
}
throw new Error("index out of bounds")
}
append(a: A): LinkedList<A> { return this.add(a) }
isEmpty(): boolean { return true }
}
class Cons<A> implements LinkedList<A> {
constructor(private _head: A, private _tail: LinkedList<A>) {}
head(): A {
return this._head;
}
tail(): LinkedList<A> {
return this._tail
}
size(): number {
return 1 + this.tail().size()
}
getN(n: number): A {
return n === 0 ? this.head() : this.tail().getN(n - 1)
}
add(a: A): LinkedList<A> {
return new Cons(a, this.tail())
}
addAt(a: A, i: number): LinkedList<A> {
return i === 0 ? this.add(a) : new Cons(this.head(), this.tail().addAt(a, i - 1))
}
append(a: A): LinkedList<A> {
return new Cons(this.head(), this.tail().append(a))
}
isEmpty(): boolean {
return false
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment