Skip to content

Commit

Permalink
(1.0.9) Allow refining either types without ===
Browse files Browse the repository at this point in the history
  • Loading branch information
danwang committed May 18, 2017
1 parent 76fed5b commit c1abfa0
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 17 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lambdanwang",
"version": "1.0.8",
"version": "1.0.9",
"main": "dist/index.js",
"scripts": {
"flow": "flow",
Expand Down
48 changes: 32 additions & 16 deletions src/either.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@
import type {Option} from './option.js';
import {some, none} from './option.js';

type EitherCommon<A, B> = {
left: LeftProjection<A, B>,
right: RightProjection<A, B>,
};
type Left<A, B> = EitherCommon<A, B> & {
isLeft: true,
isRight: false,
leftValue: A,
};

type Right<A, B> = EitherCommon<A, B> & {
isLeft: false,
isRight: true,
rightValue: B,
};

class AbstractEither<A, B> {
isLeft: $Subtype<boolean>;
isRight: $Subtype<boolean>;
Expand All @@ -17,35 +33,35 @@ class LeftProjection<A, B> {
}
get() {
const {e} = this;
if (e.isLeft === true) {
if (e.isLeft) {
return e.leftValue;
} else {
throw new Error('Either.left.value on Right');
}
}
map<X>(f: A => X): Either<X, B> {
const {e} = this;
return e.isLeft === true ? left(f(e.leftValue)) : right(e.rightValue);
return e.isLeft ? left(f(e.leftValue)) : right(e.rightValue);
}
flatMap<X>(f: A => Either<X, B>): Either<X, B> {
const {e} = this;
return e.isLeft === true ? f(e.leftValue) : right(e.rightValue);
return e.isLeft ? f(e.leftValue) : right(e.rightValue);
}
getOrElse<X>(def: X): (A | X) {
const {e} = this;
return e.isLeft === true ? e.leftValue : def;
return e.isLeft ? e.leftValue : def;
}
filter(p: A => boolean): Option<Either<A, B>> {
const {e} = this;
if (e.isLeft === true && p(e.leftValue)) {
if (e.isLeft && p(e.leftValue)) {
return some(e);
} else {
return none;
}
}
toOption(): Option<A> {
const {e} = this;
return e.isLeft === true ? some(e.leftValue) : none;
return e.isLeft ? some(e.leftValue) : none;
}
}

Expand All @@ -56,39 +72,39 @@ class RightProjection<A, B> {
}
get() {
const {e} = this;
if (e.isRight === true) {
if (e.isRight) {
return e.rightValue;
} else {
throw new Error('Either.right.value on Left');
}
}
map<X>(f: B => X): Either<A, X> {
const {e} = this;
return e.isRight === true ? right(f(e.rightValue)) : left(e.leftValue);
return e.isRight ? right(f(e.rightValue)) : left(e.leftValue);
}
flatMap<X>(f: B => Either<A, X>): Either<A, X> {
const {e} = this;
return e.isRight === true ? f(e.rightValue) : left(e.leftValue);
return e.isRight ? f(e.rightValue) : left(e.leftValue);
}
getOrElse<X>(def: X): (B | X) {
const {e} = this;
return e.isRight === true ? e.rightValue : def;
return e.isRight ? e.rightValue : def;
}
filter(p: B => boolean): Option<Either<A, B>> {
const {e} = this;
if (e.isRight === true && p(e.rightValue)) {
if (e.isRight && p(e.rightValue)) {
return some(e);
} else {
return none;
}
}
toOption(): Option<B> {
const {e} = this;
return e.isRight === true ? some(e.rightValue) : none;
return e.isRight ? some(e.rightValue) : none;
}
}

class Left<A, B> extends AbstractEither<A, B> {
class _Left<A, B> extends AbstractEither<A, B> {
leftValue: A;
constructor(leftValue: A) {
super();
Expand All @@ -98,7 +114,7 @@ class Left<A, B> extends AbstractEither<A, B> {
isRight: false = false;
}

class Right<A, B> extends AbstractEither<A, B> {
class _Right<A, B> extends AbstractEither<A, B> {
rightValue: B;
constructor(rightValue: B) {
super();
Expand All @@ -108,8 +124,8 @@ class Right<A, B> extends AbstractEither<A, B> {
isRight: true = true;
}

export const left = <A, B>(leftValue: A): Left<A, B> => new Left(leftValue);
export const right = <A, B>(rightValue: B): Right<A, B> => new Right(rightValue);
export const left = <A, B>(leftValue: A): Left<A, B> => new _Left(leftValue);
export const right = <A, B>(rightValue: B): Right<A, B> => new _Right(rightValue);

export type Either<A, B> = Left<A, B> | Right<A, B>;

Expand Down

0 comments on commit c1abfa0

Please sign in to comment.