Skip to content

Instantly share code, notes, and snippets.

@mlhaufe
Last active July 8, 2019 01:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mlhaufe/089004abd14ad8e7171e2a122198637f to your computer and use it in GitHub Desktop.
Save mlhaufe/089004abd14ad8e7171e2a122198637f to your computer and use it in GitHub Desktop.
Simulating Generics w/ Inheritance in TypeScript.
abstract class Comparable {
abstract le(other: this): boolean
min(other: this): Comparable {
return this.le(other) ? this : other
}
}
abstract class Ring {
constructor(
readonly zero: Ring,
readonly unit: Ring
) {}
abstract plus(other: Ring): Ring
abstract times(other: Ring): Ring
}
///////////////
class NumberComparable extends Comparable {
constructor (readonly value: number){ super() }
le(other: this): boolean { return this.value <= other.value }
}
class StringComparable extends Comparable {
constructor (readonly value: string){ super() }
le(other: this): boolean { return this.value <= other.value }
}
var n1 = new NumberComparable(7),
n2 = new NumberComparable(12);
var s1 = new StringComparable('a'),
s2 = new StringComparable('d')
n1.le(n2)
// s1.le(n1) //type error
abstract class Matrix {
abstract readonly of: Ring
protected _implementation: this['of'][][] = []
getEntry(i: number, j: number): this['of'] {
return this._implementation[i][j]
}
setEntry(i: number, j: number, value: this['of']): this {
this._implementation[i][j] = value
return this
}
plus(other: this): this {
// ...
return this
}
times(other: this): this {
// ...
return this
}
}
class BoolRing extends Ring {
constructor(readonly value: boolean){ super(new BoolRing(false),new BoolRing(true)) }
plus(other: this): BoolRing { return new BoolRing(this.value || other.value) }
times(other: this): BoolRing { return new BoolRing(this.value && other.value) }
}
class BoolMatrix extends Matrix { of!: BoolRing }
var b = new BoolMatrix()
class NumRing extends Ring {
constructor(readonly value: number){ super(new NumRing(0),new NumRing(1)) }
plus(other: this): NumRing { return new NumRing(this.value + other.value) }
times(other: this): NumRing { return new NumRing(this.value * other.value) }
}
class NumMatrix extends Matrix { of!: NumRing }
var n = new NumMatrix()
abstract class Queueable { abstract of: any }
abstract class Queue {
abstract readonly of: Queueable
protected _implementation: this['of'][] = []
isEmpty(): boolean { return this._implementation.length == 0 }
enqueue(element: this['of']): this {
this._implementation.push(element)
return this
}
dequeue(): this['of'] | undefined {
return this._implementation.shift()
}
size(): number { return this._implementation.length }
}
class QueueableString extends Queueable {
of!: string
constructor(readonly value: string) { super() }
}
class StringQueue extends Queue { of!: QueueableString }
class QueueableNumber extends Queueable {
of!: number
constructor(readonly value: number){ super() }
}
class NumberQueue extends Queue { of!: QueueableNumber }
@mlhaufe
Copy link
Author

mlhaufe commented Jul 15, 2017

Inspired by Bertrand Meyer's 1988 book: "Object-oriented Software Construction"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment