Created
August 9, 2018 17:03
-
-
Save mvaldesdeleon/2cf4b6ea7aaf9f2c65944f724918f072 to your computer and use it in GitHub Desktop.
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
| import fl = require('fantasy-land'); | |
| interface ILeft<A> { | |
| _: 'Left'; | |
| value: A; | |
| } | |
| interface IRight<B> { | |
| _: 'Right'; | |
| value: B; | |
| } | |
| export type Either<A, B> = ILeft<A> | IRight<B>; | |
| export const Left = <A>(value: A): ILeft<A> => ({ _: 'Left', value }); | |
| export const Right = <A>(value: A): IRight<A> => ({ _: 'Right', value }); | |
| interface IPattern<A, B, C> { | |
| Left: (value: A) => C; | |
| Right: (value: B) => C; | |
| } | |
| export const match = <A, B, C>(definition: IPattern<A, B, C>) => (eitherAB: Either<A, B>): C => { | |
| switch (eitherAB._) { | |
| case 'Left': | |
| return definition.Left(eitherAB.value); | |
| case 'Right': | |
| return definition.Right(eitherAB.value); | |
| } | |
| }; | |
| type IFn<A, B> = (a: A) => B; | |
| export const map = <A, B, C>(fn: IFn<B, C>) => (eitherAB: Either<A, B>): Either<A, C> => | |
| match({ | |
| Left: (value: A) => Left(value) as Either<A, C>, | |
| Right: (value: B) => Right(fn(value)) | |
| })(eitherAB); | |
| export const ap = <A, B, C>(eitherAFn: Either<A, IFn<B, C>>) => ( | |
| eitherAB: Either<A, B> | |
| ): Either<A, C> => | |
| match({ | |
| Left: (value: A) => Left(value), | |
| Right: (value: B) => | |
| match({ | |
| // tslint:disable-next-line:no-shadowed-variable | |
| Left: (value: A) => Left(value) as Either<A, C>, | |
| Right: (fn: IFn<B, C>) => Right(fn(value)) | |
| })(eitherAFn) | |
| })(eitherAB); | |
| export const map2 = <A, B, C, D>(fn: IFn<B, IFn<C, D>>) => (eitherAB: Either<A, B>) => ( | |
| eitherAC: Either<A, C> | |
| ): Either<A, D> => ap((map(fn) as IFn<Either<A, B>, Either<A, IFn<C, D>>>)(eitherAB))(eitherAC); | |
| // export const map2 = <A, B, C, D>(fn: IFn2<B, C, D>) => (eitherAB: Either<A, B>) => ( | |
| // eitherAC: Either<A, C> | |
| // ): Either<A, D> => ap(map(fn)(eitherAB))(eitherAC); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment