import { Parameter , unknown } from "../.." ; import { Option } from "./option" ; import { UnitLike } from "./unit" ; declare const EitherId = "typeprops/lib/data/either" ; declare module "typeprops" { interface TypeProps < T , Params > { [ EitherId ] : { infer : T extends Either < infer L , infer R > ? [ L , R ] : never ; construct : Either < Params [ 0 ] , Params [ 1 ] > ; } ; } } declare module "../abstract/functor" { interface FunctorProps < T , Params > { [ EitherId ] : { infer : T extends Either < any , infer R > ? [ R ] : never ; construct : Either < Parameter < T , 0 > , Params [ 0 ] > ; } ; } } export class Either < E , T > { static from < U , T > ( iterable , left ) { if ( iterable == undefined ) { return new Left ( left ) ; } const iterator = ( iterable as any ) [ Symbol . iterator ] ; if ( typeof iterator === "function" || iterator . toString ( ) === "[object Function]" ) { const next = iterator . next ( ) ; if ( next . done ) { return new Left ( left ) ; } else { return new Right ( next . value ) ; } } const value = iterable as any ; if ( "length" in value && 0 in value ) { return new Right ( value [ 0 ] ) ; } if ( "value" in value ) { return new Right ( value . value ) ; } return new Right ( value ) ; } static isEither < E , T > ( either ) ; static isEither ( either ) { return either instanceof Either ; } value : E | T ; protected constructor ( value ) { this . value = value ; } isLeft ( ) { return this instanceof Left ; } isRight ( ) { return this instanceof Right ; } map < U > ( transform ) { return this . isLeft ( ) ? this : new Right ( transform ( this . value as T ) ) ; } chain < U > ( transform ) { return this . isLeft ( ) ? this : transform ( this . value as T ) ; } toMaybe ( ) { return this . isLeft ( ) ? Option . nothing : new Option ( this . value ) ; } * [ Symbol . iterator ] ( ) { yield this . value ; } } export class Left < E > extends Either < E , never > { constructor ( a ) { super ( a ) ; } } export class Right < T > extends Either < never , T > { constructor ( a ) { super ( a ) ; } } export namespace Either { export const of = < T > ( a ) : Either < never , T > => new Right ( a ) ; export const isLeft = < E > ( either ) : either is Either < E , never > => either . isLeft ( ) ; export const isRight = < T > ( either ) : either is Either < never , T > => either . isRight ( ) ; export const map = < T , U , E > ( transform , either ) : Either < E , U > => either . map ( transform ) ; export const chain = < T , U , E > ( transform , either ) : Either < E , U > => either . chain ( transform ) ; }