Last active
September 2, 2018 11:21
-
-
Save mebubo/3231b176294978784e96ff5bca9d92e2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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