Skip to content

Instantly share code, notes, and snippets.

@everson
Last active August 29, 2015 14:03
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 everson/1ccec8bea924fe98220e to your computer and use it in GitHub Desktop.
Save everson/1ccec8bea924fe98220e to your computer and use it in GitHub Desktop.
Option<T> type for typescript. Just experimenting.
interface Array<T> {
flatMap <U>( fn: (a:any) => Maybe<U>): Array<U>;
// currently limited because I cannot write Array<T extends Maybe<Z>> and have flatten return Array<Z>
flatten (): Array<any>;
}
// the runtime
Array.prototype.flatMap =
function <U>(fn: (a:any) => Maybe<U>):Array<U> {
var res:Array<U> = [];
var curr:Array<Maybe<any>> = this;
var len = curr.length;
for (var i = 0; i < len; i++){
var item = fn(curr[i]);
if(item.isDefined){
res.push(item.get());
}
}
return res;
};
Array.prototype.flatten = function(){
return this.flatMap(x => x)
};
var nothingNumber = Nothing.instance<number>();
var a = new Just("name");
var b:Maybe<string> = Nothing.instance<string>();
var getSize:(string) => number = (str: string) => str.length;
var c: Maybe<number> = a.map(getSize);
// returns Just "name"
var d: Maybe<number> = b.map(getSize);
// returns Nothing
var definedValues = [c,d].flatten();
// returns [Just 4]
var typerArr: Array<number> = [10,5,0];
// divides 100 by the number provided. Returns Nothing if denon == 0
var divideBy: (number) => Maybe<number> = function (denon) {
if(denon == 0){
return Nothing.instance<number>();
} else {
return new Just(100/denon);
}
};
var divisions = typerArr.flatMap(divideBy);
// returns: [10, 20]
interface Maybe<T> {
map <U>( fn: (a:T) => U): Maybe<U>;
isDefined: boolean;
get() :T;
}
class Just<T> implements Maybe<T>{
private value: T;
constructor(v:T) {
this.value = v;
}
map <U>( fn: (a:T) => U): Maybe<U> { return new Just(fn(this.value))}
isDefined: boolean = true;
get(): T {return this.value}
toString(): string {
return "Just " + this.value;
}
}
class Nothing<T> implements Maybe<T>{
constructor() {
}
map <U>( fn: (a:T) => U): Maybe<U> {
return <Maybe<U>>Nothing._instance;
}
isDefined: boolean = false;
get(): T {throw "Nothing.get"}
private static _instance: Maybe<any> = new Nothing();
public static instance<X>(): Maybe<X> {
return <Maybe<X>> Nothing._instance;
}
public toString(): string {
return "Nothing";
}
}
@everson
Copy link
Author

everson commented Jun 29, 2014

suggestion for official support https://typescript.codeplex.com/workitem/2585

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