export interface Try { isSuccess: boolean; error?: any; flatMap(foo: (arg: T) => Try): Try map(foo: (arg: T) => U): Try; forEach(foo: (arg: T) => any): void; /// Gets the value or rethrows the exception on failure get(): T; getOrElse(ifElse: () => T): T; } class Success implements Try { value: T; isSuccess = true; constructor(value: T) { this.value = value; } flatMap(foo: (arg: T) => Try): Try { return foo(this.value); } map(foo: (arg: T) => U): Try { return apply(() => foo(this.value)); } forEach(action: (value) => any): void { action(this.value); } get(): T { return this.value; } getOrElse(orElse: () => T): T { return this.value; } } class Failure implements Try { isSuccess = false; error:any; constructor(error:any) { this.error = error; } flatMap(foo:(arg:T) => Try):Try { return new Failure(this.error); } map(foo:(arg:T) => U):Try { return new Failure(this.error); } forEach(action:(value) => any):void { } getOrElse(orElse:() => T):T { return orElse(); } get(): T { throw this.error; } } // monad return export function apply(foo: () => T): Try { try { return new Success(foo()); } catch (e) { return new Failure(e); } } export function success(value: T): Try { return new Success(value); } export function failure(errorMessage: any): Try { return new Failure(errorMessage); } export function trySequence(values: Try[]): Try { var result = []; for (let value of values) { if (!value.isSuccess) { return failure(value.error); } result.push(value.get()); } return success(result); }