Created
September 4, 2018 08:54
-
-
Save zeusdeux/76f0d32d9884e8f65e20e9225f9302f4 to your computer and use it in GitHub Desktop.
Either monad in typescript
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 type Either<L,R> = Left<L> | Right<R> | |
export class Left<L> { | |
constructor(private readonly value: L) {} | |
public getValue() { | |
return this.value | |
} | |
} | |
export class Right<R> { | |
constructor(private readonly value: R) {} | |
public getValue() { | |
return this.value | |
} | |
} | |
export function caseOf<L, R>(value: Either<L, R>, block: { left: (x: L) => any, right: (x: R) => any }) { | |
const { left, right } = block | |
const unwrappedValue = value.getValue() | |
if (value instanceof Left) return left(unwrappedValue as L) | |
else if (value instanceof Right) return right(unwrappedValue as R) | |
throw new Error('Invalid value type: ${typeof value}') | |
} |
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
const x: Either<string, Error> = new Left('sd') | |
const y = new Right(new Error()) // assignable to anything of type Either<any, Error> | |
const z: Either<number, Error> = x // type error | |
caseOf(x, { | |
left: v => console.log(`left: ${v}`), | |
right: v => console.log(`right: ${v}`) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment