Skip to content

Instantly share code, notes, and snippets.

@zeusdeux
Created September 4, 2018 08:54
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeusdeux/76f0d32d9884e8f65e20e9225f9302f4 to your computer and use it in GitHub Desktop.
Save zeusdeux/76f0d32d9884e8f65e20e9225f9302f4 to your computer and use it in GitHub Desktop.
Either monad in typescript
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}')
}
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