Skip to content

Instantly share code, notes, and snippets.

@matthieubulte
Created January 8, 2015 08:52
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 matthieubulte/e4cfe2da318098dad332 to your computer and use it in GitHub Desktop.
Save matthieubulte/e4cfe2da318098dad332 to your computer and use it in GitHub Desktop.
module either {
export interface Either<L, R> {
isLeft():boolean;
isRight():boolean;
left():L;
right():R;
either<a>(
fl:(l:L)=>a,
fr:(r:R)=>a
):a;
}
class Left<L> implements Either<L, any> {
constructor(private value:L) {}
public left():L {
return this.value;
}
public isLeft():boolean {
return true;
}
public right():any {
throw new Error("I'm left motherfucker!");
}
public isRight():boolean {
return false;
}
public either<a>(fl:(l:L)=>a, _):a {
return fl(this.value);
}
}
class Right<R> implements Either<any, R> {
constructor(private value:R) {}
public left():any {
throw new Error("I'm right motherfucker!");
}
public isLeft():boolean {
return false;
}
public right():R {
return this.value;
}
public isRight():boolean {
return true;
}
public either<a>(_, fr:(r:R)=>a):a {
return fr(this.value);
}
}
export function left<L>(val:L):Left<L> {
return new Left<L>(val);
}
export function right<R>(val:R):Right<R> {
return new Right<R>(val);
}
}
import Either = either.Either;
function increment(x:Either<number, string>):number {
return x.either(
(x:number) => x + 1,
(x:string) => parseInt(x, 10) + 1
);
}
console.log(
increment(either.left(1)) === increment(either.right("1"))
); // true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment