funfix-core
Advanced tools
Comparing version 6.2.2 to 7.0.0-rc.2
/*! | ||
* Copyright (c) 2017 by The Funfix Project Developers. | ||
* Copyright (c) 2017-2018 by The Funfix Project Developers. | ||
* Some rights reserved. | ||
@@ -17,3 +17,5 @@ * | ||
*/ | ||
import { Setoid, Monad } from "funland"; | ||
import * as std from "./std"; | ||
import { HK, HK2 } from "./kinds"; | ||
import { Throwable } from "./errors"; | ||
@@ -52,7 +54,6 @@ /** | ||
*/ | ||
export declare class Either<L, R> implements std.IEquals<Either<L, R>> { | ||
private _isRight; | ||
private _rightRef; | ||
private _leftRef; | ||
private constructor(); | ||
export declare class Either<L, R> implements std.IEquals<Either<L, R>>, HK2<"funfix/either", L, R> { | ||
readonly value: L | R; | ||
private readonly _isRight; | ||
protected constructor(value: L | R, tag: "left" | "right"); | ||
/** | ||
@@ -66,3 +67,3 @@ * Returns `true` if this is a `left`, `false` otherwise. | ||
*/ | ||
isLeft(): boolean; | ||
isLeft(): this is TLeft<L>; | ||
/** | ||
@@ -76,3 +77,3 @@ * Returns `true` if this is a `right`, `false` otherwise. | ||
*/ | ||
isRight(): boolean; | ||
isRight(): this is TRight<R>; | ||
/** | ||
@@ -93,3 +94,3 @@ * Returns true if this is a Right and its value is equal to `elem` | ||
*/ | ||
contains(elem: R): boolean; | ||
contains(elem: R): this is TRight<R>; | ||
/** | ||
@@ -110,3 +111,3 @@ * Returns `false` if the source is a `left`, or returns the result | ||
*/ | ||
exists(p: (r: R) => boolean): boolean; | ||
exists(p: (r: R) => boolean): this is TRight<R>; | ||
/** | ||
@@ -131,3 +132,3 @@ * Filters `right` values with the given predicate, returning | ||
*/ | ||
filterOrElse(p: (r: R) => boolean, zero: () => L): Either<L, R>; | ||
filterOrElse<LL>(p: (r: R) => boolean, zero: () => LL): Either<L | LL, R>; | ||
/** | ||
@@ -140,3 +141,12 @@ * Binds the given function across `right` values. | ||
flatMap<S>(f: (r: R) => Either<L, S>): Either<L, S>; | ||
/** Alias for [[flatMap]]. */ | ||
chain<S>(f: (r: R) => Either<L, S>): Either<L, S>; | ||
/** | ||
* `Applicative` apply operator. | ||
* | ||
* Resembles {@link map}, but the passed mapping function is | ||
* lifted in the `Either` context. | ||
*/ | ||
ap<S>(ff: Either<L, (a: R) => S>): Either<L, S>; | ||
/** | ||
* Applies the `left` function to [[Left]] values, and the | ||
@@ -241,10 +251,28 @@ * `right` function to [[Right]] values and returns the result. | ||
toOption(): Option<R>; | ||
/** Implements {@link IEquals.equals}. */ | ||
equals(other: Either<L, R>): boolean; | ||
/** | ||
* Implements {@link IEquals.equals}. | ||
* | ||
* @param that is the right hand side of the equality check | ||
*/ | ||
equals(that: Either<L, R>): boolean; | ||
/** Implements {@link IEquals.hashCode}. */ | ||
hashCode(): number; | ||
/** @hidden */ readonly _funKindF: Either<L, any>; | ||
/** @hidden */ readonly _funKindA: R; | ||
/** @hidden */ static readonly _funErasure: Either<any, any>; | ||
/** @hidden */ readonly _URI: "funfix/either"; | ||
/** @hidden */ readonly _A: R; | ||
/** @hidden */ readonly _L: L; | ||
/** @hidden */ static readonly _Class: Either<any, any>; | ||
/** | ||
* Builds a pure `Either` value. | ||
* | ||
* This operation is the pure `Applicative` operation for lifting | ||
* a value in the `Either` context. | ||
*/ | ||
static pure<A>(value: A): Either<never, A>; | ||
/** | ||
* Builds a left value, equivalent with {@link Left}. | ||
*/ | ||
static left<L, R>(value: L): Either<L, R>; | ||
/** | ||
* Builds a right value, equivalent with {@link Right}. | ||
*/ | ||
static right<L, R>(value: R): Either<L, R>; | ||
@@ -354,12 +382,43 @@ /** | ||
/** | ||
* Result of the [[Left]] data constructor, representing | ||
* "left" values in the [[Either]] disjunction. | ||
* | ||
* @final | ||
*/ | ||
export declare class TLeft<L> extends Either<L, never> { | ||
readonly value: L; | ||
constructor(value: L); | ||
} | ||
/** | ||
* The `Left` data constructor represents the left side of the | ||
* [[Either]] disjoint union, as opposed to the [[Right]] side. | ||
*/ | ||
export declare function Left<L>(value: L): Either<L, never>; | ||
export declare function Left<L>(value: L): TLeft<L>; | ||
/** | ||
* Result of the [[Right]] data constructor, representing | ||
* "right" values in the [[Either]] disjunction. | ||
* | ||
* @final | ||
*/ | ||
export declare class TRight<R> extends Either<never, R> { | ||
readonly value: R; | ||
constructor(value: R); | ||
} | ||
/** | ||
* The `Right` data constructor represents the right side of the | ||
* [[Either]] disjoint union, as opposed to the [[Left]] side. | ||
*/ | ||
export declare function Right<R>(value: R): Either<never, R>; | ||
export declare function Right<R>(value: R): TRight<R>; | ||
/** | ||
* Type enumerating the type-classes that `Either` implements. | ||
*/ | ||
export declare type EitherTypes = Setoid<Either<any, any>> & Monad<"funfix/either">; | ||
/** | ||
* Type-class implementations, compatible with the `static-land` | ||
* and `funland` specifications. | ||
* | ||
* See [funland-js.org](https://funland-js.org). | ||
*/ | ||
export declare const EitherModule: EitherTypes; | ||
/** | ||
* Represents optional values, inspired by Scala's `Option` and by | ||
@@ -378,6 +437,6 @@ * Haskell's `Maybe` data types. | ||
*/ | ||
export declare class Option<A> implements std.IEquals<Option<A>> { | ||
private _isEmpty; | ||
private _ref; | ||
private constructor(); | ||
export declare class Option<A> implements std.IEquals<Option<A>>, HK<"funfix/option", A> { | ||
private readonly _isEmpty; | ||
readonly value: undefined | A; | ||
protected constructor(ref: A | undefined, isEmpty?: boolean); | ||
/** | ||
@@ -435,7 +494,7 @@ * Returns the option's value. | ||
*/ | ||
isEmpty(): boolean; | ||
isEmpty(): this is TNone; | ||
/** | ||
* Returns `true` if the option is not empty, `false` otherwise. | ||
*/ | ||
nonEmpty(): boolean; | ||
nonEmpty(): this is TSome<A>; | ||
/** | ||
@@ -456,29 +515,2 @@ * Returns an option containing the result of applying `f` to | ||
/** | ||
* Returns an optioning containing the result of the source mapped | ||
* by the given function `f`. | ||
* | ||
* Similar to `map`, except that if the mapping function `f` returns | ||
* `null`, then the final result returned will be [[Option.none]]. | ||
* | ||
* Comparison: | ||
* | ||
* ```typescript | ||
* Option.of(1).mapN(x => null) // None | ||
* Option.of(1).map(x => null) // Some(null) | ||
* | ||
* Option.of(1).mapN(x => x+1) // 2 | ||
* Option.of(1).map(x => x+1) // 2 | ||
* ``` | ||
* | ||
* What this operation does is to allow for safe chaining of multiple | ||
* method calls or functions that might produce `null` results: | ||
* | ||
* ```typescript | ||
* Option.of(user) | ||
* .mapN(_ => _.contacts) | ||
* .mapN(_ => _.length) | ||
* ``` | ||
*/ | ||
mapN<B>(f: (a: A) => B | null | undefined): Option<B>; | ||
/** | ||
* Returns the result of applying `f` to this option's value if | ||
@@ -514,2 +546,9 @@ * the option is nonempty, otherwise returns an empty option. | ||
/** | ||
* `Applicative` apply operator. | ||
* | ||
* Resembles {@link map}, but the passed mapping function is | ||
* lifted in the `Either` context. | ||
*/ | ||
ap<B>(ff: Option<(a: A) => B>): Option<B>; | ||
/** | ||
* Returns this option if it is nonempty AND applying the | ||
@@ -525,2 +564,3 @@ * predicate `p` to the underlying value yields `true`, | ||
*/ | ||
filter<B extends A>(p: (a: A) => a is B): Option<B>; | ||
filter(p: (a: A) => boolean): Option<A>; | ||
@@ -571,7 +611,12 @@ /** | ||
forEach(cb: (a: A) => void): void; | ||
/** | ||
* Implements {@link IEquals.equals}. | ||
* | ||
* @param that is the right hand side of the equality check | ||
*/ | ||
equals(that: Option<A>): boolean; | ||
hashCode(): number; | ||
/** @hidden */ readonly _funKindF: Option<any>; | ||
/** @hidden */ readonly _funKindA: A; | ||
/** @hidden */ static readonly _funErasure: Option<any>; | ||
/** @hidden */ readonly _URI: "funfix/option"; | ||
/** @hidden */ readonly _A: A; | ||
/** @hidden */ static readonly _Class: Option<any>; | ||
/** | ||
@@ -608,3 +653,3 @@ * Builds an [[Option]] reference that contains the given value. | ||
*/ | ||
static none(): Option<never>; | ||
static none<A = never>(): Option<A>; | ||
/** | ||
@@ -728,2 +773,10 @@ * Returns an empty [[Option]]. | ||
/** | ||
* Result of the [[Some]] data constructor, representing | ||
* non-empty values in the [[Option]] disjunction. | ||
*/ | ||
export declare class TSome<A> extends Option<A> { | ||
readonly value: A; | ||
constructor(value: A); | ||
} | ||
/** | ||
* The `Some<A>` data constructor for [[Option]] represents existing | ||
@@ -734,4 +787,12 @@ * values of type `A`. | ||
*/ | ||
export declare function Some<A>(value: A): Option<A>; | ||
export declare function Some<A>(value: A): TSome<A>; | ||
/** | ||
* Result of the [[Some]] data constructor, representing | ||
* non-empty values in the [[Option]] disjunction. | ||
*/ | ||
export declare class TNone extends Option<never> { | ||
readonly value: undefined; | ||
private constructor(); | ||
} | ||
/** | ||
* The `None` data constructor for [[Option]] represents non-existing | ||
@@ -742,4 +803,15 @@ * values for any type. | ||
*/ | ||
export declare const None: Option<never>; | ||
export declare const None: TNone; | ||
/** | ||
* Type enumerating the type classes implemented by `Option`. | ||
*/ | ||
export declare type OptionTypes = Setoid<Option<any>> & Monad<"funfix/option">; | ||
/** | ||
* Type-class implementations, compatible with the `static-land` | ||
* and `funland` specification. | ||
* | ||
* See [funland-js.org](https://funland-js.org). | ||
*/ | ||
export declare const OptionModule: OptionTypes; | ||
/** | ||
* The `Try` type represents a computation that may either result in an | ||
@@ -790,7 +862,6 @@ * exception, or return a successfully computed value. It's similar to, | ||
*/ | ||
export declare class Try<A> implements std.IEquals<Try<A>> { | ||
export declare class Try<A> implements std.IEquals<Try<A>>, HK<"funfix/try", A> { | ||
private _isSuccess; | ||
private _successRef; | ||
private _failureRef; | ||
private constructor(); | ||
readonly value: Throwable | A; | ||
protected constructor(value: Throwable | A, tag: "failure" | "success"); | ||
/** | ||
@@ -800,3 +871,3 @@ * Returns `true` if the source is a [[Success]] result, | ||
*/ | ||
isSuccess(): boolean; | ||
isSuccess(): this is TSuccess<A>; | ||
/** | ||
@@ -806,3 +877,3 @@ * Returns `true` if the source is a [[Failure]], | ||
*/ | ||
isFailure(): boolean; | ||
isFailure(): this is TFailure; | ||
/** | ||
@@ -919,2 +990,3 @@ * Returns a Try's successful value if it's a [[Success]] reference, | ||
*/ | ||
filter<B extends A>(p: (a: A) => a is B): Try<B>; | ||
filter(p: (a: A) => boolean): Try<A>; | ||
@@ -939,2 +1011,9 @@ /** | ||
/** | ||
* `Applicative` apply operator. | ||
* | ||
* Resembles {@link map}, but the passed mapping function is | ||
* lifted in the `Either` context. | ||
*/ | ||
ap<B>(ff: Try<(a: A) => B>): Try<B>; | ||
/** | ||
* Returns a `Try` containing the result of applying `f` to | ||
@@ -1027,7 +1106,10 @@ * this option's value, but only if it's a `Success`, or | ||
toEither(): Either<Throwable, A>; | ||
/** | ||
* Implements {@link IEquals.equals} with overridable equality for `A`. | ||
*/ | ||
equals(that: Try<A>): boolean; | ||
hashCode(): number; | ||
/** @hidden */ readonly _funKindF: Try<any>; | ||
/** @hidden */ readonly _funKindA: A; | ||
/** @hidden */ static readonly _funErasure: Try<any>; | ||
/** @hidden */ readonly _URI: "funfix/try"; | ||
/** @hidden */ readonly _A: A; | ||
/** @hidden */ static readonly _Class: Try<any>; | ||
/** | ||
@@ -1224,2 +1306,12 @@ * Evaluates the given `thunk` and returns either a [[Success]], | ||
/** | ||
* Result of the [[Success]] data constructor, representing | ||
* successful values in the [[Try]] disjunction. | ||
* | ||
* @final | ||
*/ | ||
export declare class TSuccess<A> extends Try<A> { | ||
readonly value: A; | ||
constructor(value: A); | ||
} | ||
/** | ||
* The `Success` data constructor is for building [[Try]] values that | ||
@@ -1230,2 +1322,12 @@ * are successful results of computations, as opposed to [[Failure]]. | ||
/** | ||
* The `Success` data constructor is for building [[Try]] values that | ||
* are successful results of computations, as opposed to [[Failure]]. | ||
* | ||
* @final | ||
*/ | ||
export declare class TFailure extends Try<never> { | ||
readonly value: Throwable; | ||
constructor(value: Throwable); | ||
} | ||
/** | ||
* The `Failure` data constructor is for building [[Try]] values that | ||
@@ -1235,1 +1337,12 @@ * represent failures, as opposed to [[Success]]. | ||
export declare function Failure(e: Throwable): Try<never>; | ||
/** | ||
* Type enumerating the type classes implemented by `Try`. | ||
*/ | ||
export declare type TryTypes = Setoid<Try<any>> & Monad<"funfix/try">; | ||
/** | ||
* Type-class implementations, compatible with the `static-land` | ||
* and `funland` specifications. | ||
* | ||
* See [funland-js.org](https://funland-js.org). | ||
*/ | ||
export declare const TryModule: TryTypes; |
/*! | ||
* Copyright (c) 2017 by The Funfix Project Developers. | ||
* Copyright (c) 2017-2018 by The Funfix Project Developers. | ||
* Some rights reserved. | ||
@@ -19,2 +19,3 @@ * | ||
import { NoSuchElementError } from "./errors"; | ||
import { fantasyLandRegister } from "./internals"; | ||
/** | ||
@@ -53,8 +54,5 @@ * Represents a value of one of two possible types (a disjoint union). | ||
export class Either { | ||
constructor(_leftRef, _rightRef, _isRight) { | ||
this._isRight = _isRight; | ||
if (_isRight) | ||
this._rightRef = _rightRef; | ||
else | ||
this._leftRef = _leftRef; | ||
constructor(value, tag) { | ||
this._isRight = tag === "right"; | ||
this.value = value; | ||
} | ||
@@ -95,3 +93,3 @@ /** | ||
contains(elem) { | ||
return this._isRight && std.is(this._rightRef, elem); | ||
return this._isRight && std.is(this.value, elem); | ||
} | ||
@@ -114,3 +112,3 @@ /** | ||
exists(p) { | ||
return this._isRight && p(this._rightRef); | ||
return this._isRight && p(this.value); | ||
} | ||
@@ -138,3 +136,3 @@ /** | ||
return this._isRight | ||
? (p(this._rightRef) ? this : Left(zero())) | ||
? (p(this.value) ? this : Left(zero())) | ||
: this; | ||
@@ -149,5 +147,18 @@ } | ||
flatMap(f) { | ||
return this._isRight ? f(this._rightRef) : this; | ||
return this._isRight ? f(this.value) : this; | ||
} | ||
/** Alias for [[flatMap]]. */ | ||
chain(f) { | ||
return this.flatMap(f); | ||
} | ||
/** | ||
* `Applicative` apply operator. | ||
* | ||
* Resembles {@link map}, but the passed mapping function is | ||
* lifted in the `Either` context. | ||
*/ | ||
ap(ff) { | ||
return ff.flatMap(f => this.map(f)); | ||
} | ||
/** | ||
* Applies the `left` function to [[Left]] values, and the | ||
@@ -168,3 +179,3 @@ * `right` function to [[Right]] values and returns the result. | ||
fold(left, right) { | ||
return this._isRight ? right(this._rightRef) : left(this._leftRef); | ||
return this._isRight ? right(this.value) : left(this.value); | ||
} | ||
@@ -188,3 +199,3 @@ /** | ||
forAll(p) { | ||
return !this._isRight || p(this._rightRef); | ||
return !this._isRight || p(this.value); | ||
} | ||
@@ -204,3 +215,3 @@ /** | ||
if (this._isRight) | ||
return this._rightRef; | ||
return this.value; | ||
throw new NoSuchElementError("left.get()"); | ||
@@ -218,3 +229,3 @@ } | ||
getOrElse(fallback) { | ||
return this._isRight ? this._rightRef : fallback; | ||
return this._isRight ? this.value : fallback; | ||
} | ||
@@ -231,3 +242,3 @@ /** | ||
getOrElseL(thunk) { | ||
return this._isRight ? this._rightRef : thunk(); | ||
return this._isRight ? this.value : thunk(); | ||
} | ||
@@ -245,3 +256,3 @@ /** | ||
return this._isRight | ||
? Right(f(this._rightRef)) | ||
? Right(f(this.value)) | ||
: this; | ||
@@ -260,3 +271,3 @@ } | ||
if (this._isRight) | ||
cb(this._rightRef); | ||
cb(this.value); | ||
} | ||
@@ -274,4 +285,4 @@ /** | ||
return this._isRight | ||
? Left(this._rightRef) | ||
: Right(this._leftRef); | ||
? Left(this.value) | ||
: Right(this.value); | ||
} | ||
@@ -283,14 +294,14 @@ /** | ||
toOption() { | ||
return this._isRight | ||
? Option.some(this._rightRef) | ||
: Option.none(); | ||
return this._isRight ? Some(this.value) : None; | ||
} | ||
/** Implements {@link IEquals.equals}. */ | ||
equals(other) { | ||
/** | ||
* Implements {@link IEquals.equals}. | ||
* | ||
* @param that is the right hand side of the equality check | ||
*/ | ||
equals(that) { | ||
// tslint:disable-next-line:strict-type-predicates | ||
if (other == null) | ||
if (that == null) | ||
return false; | ||
if (this._isRight) | ||
return std.is(this._rightRef, other._rightRef); | ||
return std.is(this._leftRef, other._leftRef); | ||
return this._isRight === that._isRight && std.is(this.value, that.value); | ||
} | ||
@@ -300,8 +311,23 @@ /** Implements {@link IEquals.hashCode}. */ | ||
return this._isRight | ||
? std.hashCode(this._rightRef) << 2 | ||
: std.hashCode(this._leftRef) << 3; | ||
? std.hashCode(this.value) << 2 | ||
: std.hashCode(this.value) << 3; | ||
} | ||
/** | ||
* Builds a pure `Either` value. | ||
* | ||
* This operation is the pure `Applicative` operation for lifting | ||
* a value in the `Either` context. | ||
*/ | ||
static pure(value) { | ||
return new TRight(value); | ||
} | ||
/** | ||
* Builds a left value, equivalent with {@link Left}. | ||
*/ | ||
static left(value) { | ||
return Left(value); | ||
} | ||
/** | ||
* Builds a right value, equivalent with {@link Right}. | ||
*/ | ||
static right(value) { | ||
@@ -334,3 +360,3 @@ return Right(value); | ||
return fa2; | ||
return Right(f(fa1._rightRef, fa2._rightRef)); | ||
return Right(f(fa1.value, fa2.value)); | ||
} | ||
@@ -361,3 +387,3 @@ /** | ||
return fa3; | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef)); | ||
return Right(f(fa1.value, fa2.value, fa3.value)); | ||
} | ||
@@ -390,3 +416,3 @@ /** | ||
return fa4; | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef, fa4._rightRef)); | ||
return Right(f(fa1.value, fa2.value, fa3.value, fa4.value)); | ||
} | ||
@@ -421,3 +447,3 @@ /** | ||
return fa5; | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef, fa4._rightRef, fa5._rightRef)); | ||
return Right(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value)); | ||
} | ||
@@ -454,3 +480,3 @@ /** | ||
return fa6; | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef, fa4._rightRef, fa5._rightRef, fa6._rightRef)); | ||
return Right(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value, fa6.value)); | ||
} | ||
@@ -469,8 +495,8 @@ /** | ||
const result = f(cursor); | ||
if (result.isLeft()) | ||
if (!result.isRight()) | ||
return result; | ||
const some = result.get(); | ||
const some = result.value; | ||
if (some.isRight()) | ||
return Right(some.get()); | ||
cursor = some.swap().get(); | ||
return Right(some.value); | ||
cursor = some.value; | ||
} | ||
@@ -480,2 +506,11 @@ } | ||
/** | ||
* Result of the [[Left]] data constructor, representing | ||
* "left" values in the [[Either]] disjunction. | ||
* | ||
* @final | ||
*/ | ||
export class TLeft extends Either { | ||
constructor(value) { super(value, "left"); } | ||
} | ||
/** | ||
* The `Left` data constructor represents the left side of the | ||
@@ -485,5 +520,14 @@ * [[Either]] disjoint union, as opposed to the [[Right]] side. | ||
export function Left(value) { | ||
return new Either(value, null, false); | ||
return new TLeft(value); | ||
} | ||
/** | ||
* Result of the [[Right]] data constructor, representing | ||
* "right" values in the [[Either]] disjunction. | ||
* | ||
* @final | ||
*/ | ||
export class TRight extends Either { | ||
constructor(value) { super(value, "right"); } | ||
} | ||
/** | ||
* The `Right` data constructor represents the right side of the | ||
@@ -493,5 +537,27 @@ * [[Either]] disjoint union, as opposed to the [[Left]] side. | ||
export function Right(value) { | ||
return new Either(null, value, true); | ||
return new TRight(value); | ||
} | ||
/** | ||
* Type-class implementations, compatible with the `static-land` | ||
* and `funland` specifications. | ||
* | ||
* See [funland-js.org](https://funland-js.org). | ||
*/ | ||
export const EitherModule = { | ||
// Setoid | ||
equals: (x, y) => x ? x.equals(y) : !y, | ||
// Functor | ||
map: (f, fa) => fa.map(f), | ||
// Apply | ||
ap: (ff, fa) => fa.ap(ff), | ||
// Applicative | ||
of: Either.pure, | ||
// Chain | ||
chain: (f, fa) => fa.flatMap(f), | ||
// ChainRec | ||
chainRec: (f, a) => Either.tailRecM(a, a => f(Either.left, Either.right, a)) | ||
}; | ||
// Registers Fantasy-Land compatible symbols | ||
fantasyLandRegister(Either, EitherModule, EitherModule); | ||
/** | ||
* Represents optional values, inspired by Scala's `Option` and by | ||
@@ -514,3 +580,3 @@ * Haskell's `Maybe` data types. | ||
this._isEmpty = isEmpty != null ? isEmpty : (ref === null || ref === undefined); | ||
this._ref = ref; | ||
this.value = ref; | ||
} | ||
@@ -529,5 +595,4 @@ /** | ||
if (!this._isEmpty) | ||
return this._ref; | ||
else | ||
throw new NoSuchElementError("Option.get"); | ||
return this.value; | ||
throw new NoSuchElementError("Option.get"); | ||
} | ||
@@ -542,3 +607,3 @@ /** | ||
if (!this._isEmpty) | ||
return this._ref; | ||
return this.value; | ||
else | ||
@@ -553,3 +618,3 @@ return fallback; | ||
orNull() { | ||
return !this._isEmpty ? this._ref : null; | ||
return !this._isEmpty ? this.value : null; | ||
} | ||
@@ -561,3 +626,3 @@ /** | ||
orUndefined() { | ||
return !this._isEmpty ? this._ref : undefined; | ||
return !this._isEmpty ? this.value : undefined; | ||
} | ||
@@ -572,3 +637,3 @@ /** | ||
if (!this._isEmpty) | ||
return this._ref; | ||
return this.value; | ||
else | ||
@@ -622,34 +687,5 @@ return thunk(); | ||
map(f) { | ||
return this._isEmpty ? None : Some(f(this._ref)); | ||
return this._isEmpty ? None : Some(f(this.value)); | ||
} | ||
/** | ||
* Returns an optioning containing the result of the source mapped | ||
* by the given function `f`. | ||
* | ||
* Similar to `map`, except that if the mapping function `f` returns | ||
* `null`, then the final result returned will be [[Option.none]]. | ||
* | ||
* Comparison: | ||
* | ||
* ```typescript | ||
* Option.of(1).mapN(x => null) // None | ||
* Option.of(1).map(x => null) // Some(null) | ||
* | ||
* Option.of(1).mapN(x => x+1) // 2 | ||
* Option.of(1).map(x => x+1) // 2 | ||
* ``` | ||
* | ||
* What this operation does is to allow for safe chaining of multiple | ||
* method calls or functions that might produce `null` results: | ||
* | ||
* ```typescript | ||
* Option.of(user) | ||
* .mapN(_ => _.contacts) | ||
* .mapN(_ => _.length) | ||
* ``` | ||
*/ | ||
mapN(f) { | ||
return this._isEmpty ? None : Option.of(f(this._ref)); | ||
} | ||
/** | ||
* Returns the result of applying `f` to this option's value if | ||
@@ -685,3 +721,3 @@ * the option is nonempty, otherwise returns an empty option. | ||
else | ||
return f(this._ref); | ||
return f(this.value); | ||
} | ||
@@ -693,14 +729,12 @@ /** Alias for [[flatMap]]. */ | ||
/** | ||
* Returns this option if it is nonempty AND applying the | ||
* predicate `p` to the underlying value yields `true`, | ||
* otherwise return an empty option. | ||
* `Applicative` apply operator. | ||
* | ||
* @param p is the predicate function that is used to | ||
* apply filtering on the option's value | ||
* | ||
* @return a new option instance containing the value of the | ||
* source filtered with the given predicate | ||
* Resembles {@link map}, but the passed mapping function is | ||
* lifted in the `Either` context. | ||
*/ | ||
ap(ff) { | ||
return ff.flatMap(f => this.map(f)); | ||
} | ||
filter(p) { | ||
if (this._isEmpty || !p(this._ref)) | ||
if (this._isEmpty || !p(this.value)) | ||
return None; | ||
@@ -730,4 +764,3 @@ else | ||
return fallback(); | ||
else | ||
return f(this._ref); | ||
return f(this.value); | ||
} | ||
@@ -739,3 +772,3 @@ /** | ||
contains(elem) { | ||
return !this._isEmpty && std.is(this._ref, elem); | ||
return !this._isEmpty && std.is(this.value, elem); | ||
} | ||
@@ -749,3 +782,3 @@ /** | ||
exists(p) { | ||
return !this._isEmpty && p(this._ref); | ||
return !this._isEmpty && p(this.value); | ||
} | ||
@@ -759,3 +792,3 @@ /** | ||
forAll(p) { | ||
return this._isEmpty || p(this._ref); | ||
return this._isEmpty || p(this.value); | ||
} | ||
@@ -770,5 +803,9 @@ /** | ||
if (!this._isEmpty) | ||
cb(this._ref); | ||
cb(this.value); | ||
} | ||
// Implemented from IEquals | ||
/** | ||
* Implements {@link IEquals.equals}. | ||
* | ||
* @param that is the right hand side of the equality check | ||
*/ | ||
equals(that) { | ||
@@ -779,5 +816,3 @@ // tslint:disable-next-line:strict-type-predicates | ||
if (this.nonEmpty() && that.nonEmpty()) { | ||
const l = this.get(); | ||
const r = that.get(); | ||
return std.is(l, r); | ||
return std.is(this.value, that.value); | ||
} | ||
@@ -790,6 +825,6 @@ return this.isEmpty() && that.isEmpty(); | ||
return 2433880; | ||
else if (this._ref == null) | ||
else if (this.value == null) | ||
return 2433881 << 2; | ||
else | ||
return std.hashCode(this._ref) << 2; | ||
return std.hashCode(this.value) << 2; | ||
} | ||
@@ -872,3 +907,3 @@ /** | ||
return fa1.nonEmpty() && fa2.nonEmpty() | ||
? Some(f(fa1.get(), fa2.get())) | ||
? Some(f(fa1.value, fa2.value)) | ||
: None; | ||
@@ -895,3 +930,3 @@ } | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() | ||
? Some(f(fa1.get(), fa2.get(), fa3.get())) | ||
? Some(f(fa1.value, fa2.value, fa3.value)) | ||
: None; | ||
@@ -918,3 +953,3 @@ } | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() | ||
? Some(f(fa1.get(), fa2.get(), fa3.get(), fa4.get())) | ||
? Some(f(fa1.value, fa2.value, fa3.value, fa4.value)) | ||
: None; | ||
@@ -941,3 +976,3 @@ } | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() && fa5.nonEmpty() | ||
? Some(f(fa1.get(), fa2.get(), fa3.get(), fa4.get(), fa5.get())) | ||
? Some(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value)) | ||
: None; | ||
@@ -964,3 +999,3 @@ } | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() && fa5.nonEmpty() && fa6.nonEmpty() | ||
? Some(f(fa1.get(), fa2.get(), fa3.get(), fa4.get(), fa5.get(), fa6.get())) | ||
? Some(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value, fa6.value)) | ||
: None; | ||
@@ -980,8 +1015,11 @@ } | ||
const result = f(cursor); | ||
if (result.isEmpty()) | ||
if (result.nonEmpty()) { | ||
const some = result.value; | ||
if (some.isRight()) | ||
return Some(some.value); | ||
cursor = some.value; | ||
} | ||
else { | ||
return None; | ||
const some = result.get(); | ||
if (some.isRight()) | ||
return Some(some.get()); | ||
cursor = some.swap().get(); | ||
} | ||
} | ||
@@ -991,2 +1029,9 @@ } | ||
/** | ||
* Result of the [[Some]] data constructor, representing | ||
* non-empty values in the [[Option]] disjunction. | ||
*/ | ||
export class TSome extends Option { | ||
constructor(value) { super(value, false); } | ||
} | ||
/** | ||
* The `Some<A>` data constructor for [[Option]] represents existing | ||
@@ -998,10 +1043,10 @@ * values of type `A`. | ||
export function Some(value) { | ||
return new Option(value, false); | ||
return new TSome(value); | ||
} | ||
/** @Hidden */ | ||
function emptyOptionRef() { | ||
// Ugly workaround to get around the limitation of | ||
// Option's private constructor | ||
const F = Option; | ||
return new F(null, true); | ||
/** | ||
* Result of the [[Some]] data constructor, representing | ||
* non-empty values in the [[Option]] disjunction. | ||
*/ | ||
export class TNone extends Option { | ||
constructor() { super(undefined, true); } | ||
} | ||
@@ -1014,4 +1059,26 @@ /** | ||
*/ | ||
export const None = emptyOptionRef(); | ||
export const None = new TNone(); | ||
/** | ||
* Type-class implementations, compatible with the `static-land` | ||
* and `funland` specification. | ||
* | ||
* See [funland-js.org](https://funland-js.org). | ||
*/ | ||
export const OptionModule = { | ||
// Setoid | ||
equals: (x, y) => x ? x.equals(y) : !y, | ||
// Functor | ||
map: (f, fa) => fa.map(f), | ||
// Apply | ||
ap: (ff, fa) => fa.ap(ff), | ||
// Applicative | ||
of: Option.pure, | ||
// Chain | ||
chain: (f, fa) => fa.flatMap(f), | ||
// ChainRec | ||
chainRec: (f, a) => Option.tailRecM(a, a => f(Either.left, Either.right, a)) | ||
}; | ||
// Registers Fantasy-Land compatible symbols | ||
fantasyLandRegister(Option, OptionModule, OptionModule); | ||
/** | ||
* The `Try` type represents a computation that may either result in an | ||
@@ -1063,8 +1130,5 @@ * exception, or return a successfully computed value. It's similar to, | ||
export class Try { | ||
constructor(_success, _failure, _isSuccess) { | ||
this._isSuccess = _isSuccess; | ||
if (_isSuccess) | ||
this._successRef = _success; | ||
else | ||
this._failureRef = _failure; | ||
constructor(value, tag) { | ||
this._isSuccess = tag === "success"; | ||
this.value = value; | ||
} | ||
@@ -1092,4 +1156,4 @@ /** | ||
if (!this._isSuccess) | ||
throw this._failureRef; | ||
return this._successRef; | ||
throw this.value; | ||
return this.value; | ||
} | ||
@@ -1106,3 +1170,3 @@ /** | ||
getOrElse(fallback) { | ||
return this._isSuccess ? this._successRef : fallback; | ||
return this._isSuccess ? this.value : fallback; | ||
} | ||
@@ -1119,3 +1183,3 @@ /** | ||
getOrElseL(thunk) { | ||
return this._isSuccess ? this._successRef : thunk(); | ||
return this._isSuccess ? this.value : thunk(); | ||
} | ||
@@ -1138,3 +1202,3 @@ /** | ||
orNull() { | ||
return this._isSuccess ? this._successRef : null; | ||
return this._isSuccess ? this.value : null; | ||
} | ||
@@ -1157,3 +1221,3 @@ /** | ||
orUndefined() { | ||
return this._isSuccess ? this._successRef : undefined; | ||
return this._isSuccess ? this.value : undefined; | ||
} | ||
@@ -1197,3 +1261,3 @@ /** | ||
? Failure(new NoSuchElementError("try.failed()")) | ||
: Success(this._failureRef); | ||
: Success(this.value); | ||
} | ||
@@ -1217,11 +1281,5 @@ /** | ||
return this._isSuccess | ||
? success(this._successRef) | ||
: failure(this._failureRef); | ||
? success(this.value) | ||
: failure(this.value); | ||
} | ||
/** | ||
* Returns a [[Failure]] if the source is a [[Success]], but the | ||
* given `p` predicate is not satisfied. | ||
* | ||
* @throws NoSuchElementError in case the predicate doesn't hold | ||
*/ | ||
filter(p) { | ||
@@ -1231,5 +1289,5 @@ if (!this._isSuccess) | ||
try { | ||
if (p(this._successRef)) | ||
if (p(this.value)) | ||
return this; | ||
return Failure(new NoSuchElementError(`Predicate does not hold for ${this._successRef}`)); | ||
return Failure(new NoSuchElementError(`Predicate does not hold for ${this.value}`)); | ||
} | ||
@@ -1258,3 +1316,3 @@ catch (e) { | ||
try { | ||
return f(this._successRef); | ||
return f(this.value); | ||
} | ||
@@ -1270,2 +1328,11 @@ catch (e) { | ||
/** | ||
* `Applicative` apply operator. | ||
* | ||
* Resembles {@link map}, but the passed mapping function is | ||
* lifted in the `Either` context. | ||
*/ | ||
ap(ff) { | ||
return ff.flatMap(f => this.map(f)); | ||
} | ||
/** | ||
* Returns a `Try` containing the result of applying `f` to | ||
@@ -1286,3 +1353,3 @@ * this option's value, but only if it's a `Success`, or | ||
return this._isSuccess | ||
? Try.of(() => f(this._successRef)) | ||
? Try.of(() => f(this.value)) | ||
: this; | ||
@@ -1296,3 +1363,3 @@ } | ||
if (this._isSuccess) | ||
cb(this._successRef); | ||
cb(this.value); | ||
} | ||
@@ -1320,3 +1387,5 @@ /** | ||
recover(f) { | ||
return this._isSuccess ? this : Try.of(() => f(this._failureRef)); | ||
return this._isSuccess | ||
? this | ||
: Try.of(() => f(this.value)); | ||
} | ||
@@ -1345,3 +1414,3 @@ /** | ||
try { | ||
return this._isSuccess ? this : f(this._failureRef); | ||
return this._isSuccess ? this : f(this.value); | ||
} | ||
@@ -1365,3 +1434,3 @@ catch (e) { | ||
toOption() { | ||
return this._isSuccess ? Some(this._successRef) : None; | ||
return this._isSuccess ? Some(this.value) : None; | ||
} | ||
@@ -1382,6 +1451,8 @@ /** | ||
return this._isSuccess | ||
? Right(this._successRef) | ||
: Left(this._failureRef); | ||
? Right(this.value) | ||
: Left(this.value); | ||
} | ||
// Implemented from IEquals | ||
/** | ||
* Implements {@link IEquals.equals} with overridable equality for `A`. | ||
*/ | ||
equals(that) { | ||
@@ -1392,4 +1463,4 @@ // tslint:disable-next-line:strict-type-predicates | ||
return this._isSuccess | ||
? that._isSuccess && std.is(this._successRef, that._successRef) | ||
: !that._isSuccess && std.is(this._failureRef, that._failureRef); | ||
? that._isSuccess && std.is(this.value, that.value) | ||
: !that._isSuccess && std.is(this.value, that.value); | ||
} | ||
@@ -1399,4 +1470,4 @@ // Implemented from IEquals | ||
return this._isSuccess | ||
? std.hashCode(this._successRef) | ||
: std.hashCode(this._failureRef); | ||
? std.hashCode(this.value) | ||
: std.hashCode(this.value); | ||
} | ||
@@ -1482,3 +1553,3 @@ /** | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef)); | ||
return Success(f(fa1.value, fa2.value)); | ||
} | ||
@@ -1522,3 +1593,3 @@ catch (e) { | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef, fa3._successRef)); | ||
return Success(f(fa1.value, fa2.value, fa3.value)); | ||
} | ||
@@ -1565,3 +1636,3 @@ catch (e) { | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef, fa3._successRef, fa4._successRef)); | ||
return Success(f(fa1.value, fa2.value, fa3.value, fa4.value)); | ||
} | ||
@@ -1617,3 +1688,3 @@ catch (e) { | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef, fa3._successRef, fa4._successRef, fa5._successRef)); | ||
return Success(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value)); | ||
} | ||
@@ -1673,3 +1744,3 @@ catch (e) { | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef, fa3._successRef, fa4._successRef, fa5._successRef, fa6._successRef)); | ||
return Success(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value, fa6.value)); | ||
} | ||
@@ -1697,4 +1768,4 @@ catch (e) { | ||
if (some.isRight()) | ||
return Success(some.get()); | ||
cursor = some.swap().get(); | ||
return Success(some.value); | ||
cursor = some.value; | ||
} | ||
@@ -1708,2 +1779,11 @@ catch (e) { | ||
/** | ||
* Result of the [[Success]] data constructor, representing | ||
* successful values in the [[Try]] disjunction. | ||
* | ||
* @final | ||
*/ | ||
export class TSuccess extends Try { | ||
constructor(value) { super(value, "success"); } | ||
} | ||
/** | ||
* The `Success` data constructor is for building [[Try]] values that | ||
@@ -1713,5 +1793,14 @@ * are successful results of computations, as opposed to [[Failure]]. | ||
export function Success(value) { | ||
return new Try(value, null, true); | ||
return new TSuccess(value); | ||
} | ||
/** | ||
* The `Success` data constructor is for building [[Try]] values that | ||
* are successful results of computations, as opposed to [[Failure]]. | ||
* | ||
* @final | ||
*/ | ||
export class TFailure extends Try { | ||
constructor(value) { super(value, "failure"); } | ||
} | ||
/** | ||
* The `Failure` data constructor is for building [[Try]] values that | ||
@@ -1721,10 +1810,33 @@ * represent failures, as opposed to [[Success]]. | ||
export function Failure(e) { | ||
return new Try(null, e, false); | ||
return new TFailure(e); | ||
} | ||
/** | ||
* Type-class implementations, compatible with the `static-land` | ||
* and `funland` specifications. | ||
* | ||
* See [funland-js.org](https://funland-js.org). | ||
*/ | ||
export const TryModule = { | ||
// Setoid | ||
equals: (x, y) => x ? x.equals(y) : !y, | ||
// Functor | ||
map: (f, fa) => fa.map(f), | ||
// Apply | ||
ap: (ff, fa) => fa.ap(ff), | ||
// Applicative | ||
of: Try.pure, | ||
// Chain | ||
chain: (f, fa) => fa.flatMap(f), | ||
// ChainRec | ||
chainRec: (f, a) => Try.tailRecM(a, a => f(Either.left, Either.right, a)) | ||
}; | ||
// Registers Fantasy-Land compatible symbols | ||
fantasyLandRegister(Try, TryModule, TryModule); | ||
/** | ||
* Reusable reference, to use in {@link Try.unit}. | ||
* | ||
* @private | ||
* @hidden | ||
*/ | ||
const tryUnitRef = Success(undefined); | ||
//# sourceMappingURL=disjunctions.js.map |
/*! | ||
* Copyright (c) 2017 by The Funfix Project Developers. | ||
* Copyright (c) 2017-2018 by The Funfix Project Developers. | ||
* Some rights reserved. | ||
@@ -4,0 +4,0 @@ * |
/*! | ||
* Copyright (c) 2017 by The Funfix Project Developers. | ||
* Copyright (c) 2017-2018 by The Funfix Project Developers. | ||
* Some rights reserved. | ||
@@ -4,0 +4,0 @@ * |
572
dist/es5.js
@@ -31,2 +31,4 @@ function isValueObject(ref) { | ||
var universalSetoid = { equals: equals }; | ||
function hashCode(ref) { | ||
@@ -71,119 +73,2 @@ if (typeof ref === "number") { | ||
var asyncGenerator = function () { | ||
function AwaitValue(value) { | ||
this.value = value; | ||
} | ||
function AsyncGenerator(gen) { | ||
var front, back; | ||
function send(key, arg) { | ||
return new Promise(function (resolve, reject) { | ||
var request = { | ||
key: key, | ||
arg: arg, | ||
resolve: resolve, | ||
reject: reject, | ||
next: null | ||
}; | ||
if (back) { | ||
back = back.next = request; | ||
} else { | ||
front = back = request; | ||
resume(key, arg); | ||
} | ||
}); | ||
} | ||
function resume(key, arg) { | ||
try { | ||
var result = gen[key](arg); | ||
var value = result.value; | ||
if (value instanceof AwaitValue) { | ||
Promise.resolve(value.value).then(function (arg) { | ||
resume("next", arg); | ||
}, function (arg) { | ||
resume("throw", arg); | ||
}); | ||
} else { | ||
settle(result.done ? "return" : "normal", result.value); | ||
} | ||
} catch (err) { | ||
settle("throw", err); | ||
} | ||
} | ||
function settle(type, value) { | ||
switch (type) { | ||
case "return": | ||
front.resolve({ | ||
value: value, | ||
done: true | ||
}); | ||
break; | ||
case "throw": | ||
front.reject(value); | ||
break; | ||
default: | ||
front.resolve({ | ||
value: value, | ||
done: false | ||
}); | ||
break; | ||
} | ||
front = front.next; | ||
if (front) { | ||
resume(front.key, front.arg); | ||
} else { | ||
back = null; | ||
} | ||
} | ||
this._invoke = send; | ||
if (typeof gen.return !== "function") { | ||
this.return = undefined; | ||
} | ||
} | ||
if (typeof Symbol === "function" && Symbol.asyncIterator) { | ||
AsyncGenerator.prototype[Symbol.asyncIterator] = function () { | ||
return this; | ||
}; | ||
} | ||
AsyncGenerator.prototype.next = function (arg) { | ||
return this._invoke("next", arg); | ||
}; | ||
AsyncGenerator.prototype.throw = function (arg) { | ||
return this._invoke("throw", arg); | ||
}; | ||
AsyncGenerator.prototype.return = function (arg) { | ||
return this._invoke("return", arg); | ||
}; | ||
return { | ||
wrap: function (fn) { | ||
return function () { | ||
return new AsyncGenerator(fn.apply(this, arguments)); | ||
}; | ||
}, | ||
await: function (value) { | ||
return new AwaitValue(value); | ||
} | ||
}; | ||
}(); | ||
var classCallCheck = function (instance, Constructor) { | ||
@@ -449,8 +334,74 @@ if (!(instance instanceof Constructor)) { | ||
function convertToMethod(f) { | ||
return function () { | ||
var args = Array.prototype.slice.call(arguments); | ||
args.push(this); | ||
return f.apply(undefined, args); | ||
}; | ||
} | ||
function fantasyLandRegister(cls, monad, setoid) { | ||
var c = cls; | ||
var p = c.prototype; | ||
var fl = "fantasy-land/"; | ||
var equals = "equals"; | ||
var flEquals = fl + equals; | ||
var map = "map"; | ||
var flMap = fl + map; | ||
var ap = "ap"; | ||
var flAp = fl + ap; | ||
var flOf = fl + "of"; | ||
var chain = "chain"; | ||
var flChain = fl + chain; | ||
var chainRec = "chainRec"; | ||
var flChainRec = fl + chainRec; | ||
if (p[equals]) { | ||
p[flEquals] = p[equals]; | ||
} else { | ||
if (setoid) p[flEquals] = convertToMethod(setoid.equals); | ||
} | ||
if (p[map]) { | ||
p[flMap] = p[map]; | ||
} else { | ||
if (monad) p[flMap] = convertToMethod(monad.map); | ||
} | ||
if (p[ap]) { | ||
p[flAp] = p[ap]; | ||
} else { | ||
if (monad) p[flAp] = convertToMethod(monad.ap); | ||
} | ||
if (c["pure"]) { | ||
c[flOf] = c["pure"]; | ||
} else { | ||
if (monad) c[flOf] = monad.of; | ||
} | ||
if (p[chain]) { | ||
p[flChain] = p[chain]; | ||
} else { | ||
if (monad) p[flChain] = convertToMethod(monad.chain); | ||
} | ||
if (c[chainRec]) { | ||
c[flChainRec] = c[chainRec]; | ||
} else { | ||
if (monad) c[flChainRec] = monad.chainRec; | ||
} | ||
} | ||
var internals = Object.freeze({ | ||
convertToMethod: convertToMethod, | ||
fantasyLandRegister: fantasyLandRegister | ||
}); | ||
var Either = function () { | ||
function Either(_leftRef, _rightRef, _isRight) { | ||
function Either(value, tag) { | ||
classCallCheck(this, Either); | ||
this._isRight = _isRight; | ||
if (_isRight) this._rightRef = _rightRef;else this._leftRef = _leftRef; | ||
this._isRight = tag === "right"; | ||
this.value = value; | ||
} | ||
@@ -471,3 +422,3 @@ | ||
value: function contains(elem) { | ||
return this._isRight && is(this._rightRef, elem); | ||
return this._isRight && is(this.value, elem); | ||
} | ||
@@ -477,3 +428,3 @@ }, { | ||
value: function exists(p) { | ||
return this._isRight && p(this._rightRef); | ||
return this._isRight && p(this.value); | ||
} | ||
@@ -483,3 +434,3 @@ }, { | ||
value: function filterOrElse(p, zero) { | ||
return this._isRight ? p(this._rightRef) ? this : Left(zero()) : this; | ||
return this._isRight ? p(this.value) ? this : Left(zero()) : this; | ||
} | ||
@@ -489,8 +440,22 @@ }, { | ||
value: function flatMap(f) { | ||
return this._isRight ? f(this._rightRef) : this; | ||
return this._isRight ? f(this.value) : this; | ||
} | ||
}, { | ||
key: "chain", | ||
value: function chain(f) { | ||
return this.flatMap(f); | ||
} | ||
}, { | ||
key: "ap", | ||
value: function ap(ff) { | ||
var _this = this; | ||
return ff.flatMap(function (f) { | ||
return _this.map(f); | ||
}); | ||
} | ||
}, { | ||
key: "fold", | ||
value: function fold(left, right) { | ||
return this._isRight ? right(this._rightRef) : left(this._leftRef); | ||
return this._isRight ? right(this.value) : left(this.value); | ||
} | ||
@@ -500,3 +465,3 @@ }, { | ||
value: function forAll(p) { | ||
return !this._isRight || p(this._rightRef); | ||
return !this._isRight || p(this.value); | ||
} | ||
@@ -506,3 +471,3 @@ }, { | ||
value: function get$$1() { | ||
if (this._isRight) return this._rightRef; | ||
if (this._isRight) return this.value; | ||
throw new NoSuchElementError("left.get()"); | ||
@@ -513,3 +478,3 @@ } | ||
value: function getOrElse(fallback) { | ||
return this._isRight ? this._rightRef : fallback; | ||
return this._isRight ? this.value : fallback; | ||
} | ||
@@ -519,3 +484,3 @@ }, { | ||
value: function getOrElseL(thunk) { | ||
return this._isRight ? this._rightRef : thunk(); | ||
return this._isRight ? this.value : thunk(); | ||
} | ||
@@ -525,3 +490,3 @@ }, { | ||
value: function map(f) { | ||
return this._isRight ? Right(f(this._rightRef)) : this; | ||
return this._isRight ? Right(f(this.value)) : this; | ||
} | ||
@@ -531,3 +496,3 @@ }, { | ||
value: function forEach(cb) { | ||
if (this._isRight) cb(this._rightRef); | ||
if (this._isRight) cb(this.value); | ||
} | ||
@@ -537,3 +502,3 @@ }, { | ||
value: function swap() { | ||
return this._isRight ? Left(this._rightRef) : Right(this._leftRef); | ||
return this._isRight ? Left(this.value) : Right(this.value); | ||
} | ||
@@ -543,10 +508,9 @@ }, { | ||
value: function toOption() { | ||
return this._isRight ? Option.some(this._rightRef) : Option.none(); | ||
return this._isRight ? Some(this.value) : None; | ||
} | ||
}, { | ||
key: "equals", | ||
value: function equals$$1(other) { | ||
if (other == null) return false; | ||
if (this._isRight) return is(this._rightRef, other._rightRef); | ||
return is(this._leftRef, other._leftRef); | ||
value: function equals$$1(that) { | ||
if (that == null) return false; | ||
return this._isRight === that._isRight && is(this.value, that.value); | ||
} | ||
@@ -556,5 +520,10 @@ }, { | ||
value: function hashCode$$1() { | ||
return this._isRight ? hashCode(this._rightRef) << 2 : hashCode(this._leftRef) << 3; | ||
return this._isRight ? hashCode(this.value) << 2 : hashCode(this.value) << 3; | ||
} | ||
}], [{ | ||
key: "pure", | ||
value: function pure(value) { | ||
return new TRight(value); | ||
} | ||
}, { | ||
key: "left", | ||
@@ -574,3 +543,3 @@ value: function left(value) { | ||
if (fa2.isLeft()) return fa2; | ||
return Right(f(fa1._rightRef, fa2._rightRef)); | ||
return Right(f(fa1.value, fa2.value)); | ||
} | ||
@@ -583,3 +552,3 @@ }, { | ||
if (fa3.isLeft()) return fa3; | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef)); | ||
return Right(f(fa1.value, fa2.value, fa3.value)); | ||
} | ||
@@ -593,3 +562,3 @@ }, { | ||
if (fa4.isLeft()) return fa4; | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef, fa4._rightRef)); | ||
return Right(f(fa1.value, fa2.value, fa3.value, fa4.value)); | ||
} | ||
@@ -604,3 +573,3 @@ }, { | ||
if (fa5.isLeft()) return fa5; | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef, fa4._rightRef, fa5._rightRef)); | ||
return Right(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value)); | ||
} | ||
@@ -616,3 +585,3 @@ }, { | ||
if (fa6.isLeft()) return fa6; | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef, fa4._rightRef, fa5._rightRef, fa6._rightRef)); | ||
return Right(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value, fa6.value)); | ||
} | ||
@@ -625,6 +594,6 @@ }, { | ||
var result = f(cursor); | ||
if (result.isLeft()) return result; | ||
var some = result.get(); | ||
if (some.isRight()) return Right(some.get()); | ||
cursor = some.swap().get(); | ||
if (!result.isRight()) return result; | ||
var some = result.value; | ||
if (some.isRight()) return Right(some.value); | ||
cursor = some.value; | ||
} | ||
@@ -636,10 +605,60 @@ } | ||
var TLeft = function (_Either) { | ||
inherits(TLeft, _Either); | ||
function TLeft(value) { | ||
classCallCheck(this, TLeft); | ||
return possibleConstructorReturn(this, (TLeft.__proto__ || Object.getPrototypeOf(TLeft)).call(this, value, "left")); | ||
} | ||
return TLeft; | ||
}(Either); | ||
function Left(value) { | ||
return new Either(value, null, false); | ||
return new TLeft(value); | ||
} | ||
var TRight = function (_Either2) { | ||
inherits(TRight, _Either2); | ||
function TRight(value) { | ||
classCallCheck(this, TRight); | ||
return possibleConstructorReturn(this, (TRight.__proto__ || Object.getPrototypeOf(TRight)).call(this, value, "right")); | ||
} | ||
return TRight; | ||
}(Either); | ||
function Right(value) { | ||
return new Either(null, value, true); | ||
return new TRight(value); | ||
} | ||
var EitherModule = { | ||
equals: function equals$$1(x, y) { | ||
return x ? x.equals(y) : !y; | ||
}, | ||
map: function map(f, fa) { | ||
return fa.map(f); | ||
}, | ||
ap: function ap(ff, fa) { | ||
return fa.ap(ff); | ||
}, | ||
of: Either.pure, | ||
chain: function chain(f, fa) { | ||
return fa.flatMap(f); | ||
}, | ||
chainRec: function chainRec(f, a) { | ||
return Either.tailRecM(a, function (a) { | ||
return f(Either.left, Either.right, a); | ||
}); | ||
} | ||
}; | ||
fantasyLandRegister(Either, EitherModule, EitherModule); | ||
var Option = function () { | ||
@@ -650,3 +669,3 @@ function Option(ref, isEmpty) { | ||
this._isEmpty = isEmpty != null ? isEmpty : ref === null || ref === undefined; | ||
this._ref = ref; | ||
this.value = ref; | ||
} | ||
@@ -657,3 +676,4 @@ | ||
value: function get$$1() { | ||
if (!this._isEmpty) return this._ref;else throw new NoSuchElementError("Option.get"); | ||
if (!this._isEmpty) return this.value; | ||
throw new NoSuchElementError("Option.get"); | ||
} | ||
@@ -663,3 +683,3 @@ }, { | ||
value: function getOrElse(fallback) { | ||
if (!this._isEmpty) return this._ref;else return fallback; | ||
if (!this._isEmpty) return this.value;else return fallback; | ||
} | ||
@@ -669,3 +689,3 @@ }, { | ||
value: function orNull() { | ||
return !this._isEmpty ? this._ref : null; | ||
return !this._isEmpty ? this.value : null; | ||
} | ||
@@ -675,3 +695,3 @@ }, { | ||
value: function orUndefined() { | ||
return !this._isEmpty ? this._ref : undefined; | ||
return !this._isEmpty ? this.value : undefined; | ||
} | ||
@@ -681,3 +701,3 @@ }, { | ||
value: function getOrElseL(thunk) { | ||
if (!this._isEmpty) return this._ref;else return thunk(); | ||
if (!this._isEmpty) return this.value;else return thunk(); | ||
} | ||
@@ -707,13 +727,8 @@ }, { | ||
value: function map(f) { | ||
return this._isEmpty ? None : Some(f(this._ref)); | ||
return this._isEmpty ? None : Some(f(this.value)); | ||
} | ||
}, { | ||
key: "mapN", | ||
value: function mapN(f) { | ||
return this._isEmpty ? None : Option.of(f(this._ref)); | ||
} | ||
}, { | ||
key: "flatMap", | ||
value: function flatMap(f) { | ||
if (this._isEmpty) return None;else return f(this._ref); | ||
if (this._isEmpty) return None;else return f(this.value); | ||
} | ||
@@ -726,5 +741,14 @@ }, { | ||
}, { | ||
key: "ap", | ||
value: function ap(ff) { | ||
var _this4 = this; | ||
return ff.flatMap(function (f) { | ||
return _this4.map(f); | ||
}); | ||
} | ||
}, { | ||
key: "filter", | ||
value: function filter(p) { | ||
if (this._isEmpty || !p(this._ref)) return None;else return this; | ||
if (this._isEmpty || !p(this.value)) return None;else return this; | ||
} | ||
@@ -734,3 +758,4 @@ }, { | ||
value: function fold(fallback, f) { | ||
if (this._isEmpty) return fallback();else return f(this._ref); | ||
if (this._isEmpty) return fallback(); | ||
return f(this.value); | ||
} | ||
@@ -740,3 +765,3 @@ }, { | ||
value: function contains(elem) { | ||
return !this._isEmpty && is(this._ref, elem); | ||
return !this._isEmpty && is(this.value, elem); | ||
} | ||
@@ -746,3 +771,3 @@ }, { | ||
value: function exists(p) { | ||
return !this._isEmpty && p(this._ref); | ||
return !this._isEmpty && p(this.value); | ||
} | ||
@@ -752,3 +777,3 @@ }, { | ||
value: function forAll(p) { | ||
return this._isEmpty || p(this._ref); | ||
return this._isEmpty || p(this.value); | ||
} | ||
@@ -758,3 +783,3 @@ }, { | ||
value: function forEach(cb) { | ||
if (!this._isEmpty) cb(this._ref); | ||
if (!this._isEmpty) cb(this.value); | ||
} | ||
@@ -766,5 +791,3 @@ }, { | ||
if (this.nonEmpty() && that.nonEmpty()) { | ||
var l = this.get(); | ||
var r = that.get(); | ||
return is(l, r); | ||
return is(this.value, that.value); | ||
} | ||
@@ -776,3 +799,3 @@ return this.isEmpty() && that.isEmpty(); | ||
value: function hashCode$$1() { | ||
if (this._isEmpty) return 2433880;else if (this._ref == null) return 2433881 << 2;else return hashCode(this._ref) << 2; | ||
if (this._isEmpty) return 2433880;else if (this.value == null) return 2433881 << 2;else return hashCode(this.value) << 2; | ||
} | ||
@@ -807,3 +830,3 @@ }], [{ | ||
value: function map2(fa1, fa2, f) { | ||
return fa1.nonEmpty() && fa2.nonEmpty() ? Some(f(fa1.get(), fa2.get())) : None; | ||
return fa1.nonEmpty() && fa2.nonEmpty() ? Some(f(fa1.value, fa2.value)) : None; | ||
} | ||
@@ -813,3 +836,3 @@ }, { | ||
value: function map3(fa1, fa2, fa3, f) { | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() ? Some(f(fa1.get(), fa2.get(), fa3.get())) : None; | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() ? Some(f(fa1.value, fa2.value, fa3.value)) : None; | ||
} | ||
@@ -819,3 +842,3 @@ }, { | ||
value: function map4(fa1, fa2, fa3, fa4, f) { | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() ? Some(f(fa1.get(), fa2.get(), fa3.get(), fa4.get())) : None; | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() ? Some(f(fa1.value, fa2.value, fa3.value, fa4.value)) : None; | ||
} | ||
@@ -825,3 +848,3 @@ }, { | ||
value: function map5(fa1, fa2, fa3, fa4, fa5, f) { | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() && fa5.nonEmpty() ? Some(f(fa1.get(), fa2.get(), fa3.get(), fa4.get(), fa5.get())) : None; | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() && fa5.nonEmpty() ? Some(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value)) : None; | ||
} | ||
@@ -831,3 +854,3 @@ }, { | ||
value: function map6(fa1, fa2, fa3, fa4, fa5, fa6, f) { | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() && fa5.nonEmpty() && fa6.nonEmpty() ? Some(f(fa1.get(), fa2.get(), fa3.get(), fa4.get(), fa5.get(), fa6.get())) : None; | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() && fa5.nonEmpty() && fa6.nonEmpty() ? Some(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value, fa6.value)) : None; | ||
} | ||
@@ -840,6 +863,9 @@ }, { | ||
var result = f(cursor); | ||
if (result.isEmpty()) return None; | ||
var some = result.get(); | ||
if (some.isRight()) return Some(some.get()); | ||
cursor = some.swap().get(); | ||
if (result.nonEmpty()) { | ||
var some = result.value; | ||
if (some.isRight()) return Some(some.value); | ||
cursor = some.value; | ||
} else { | ||
return None; | ||
} | ||
} | ||
@@ -851,19 +877,64 @@ } | ||
var TSome = function (_Option) { | ||
inherits(TSome, _Option); | ||
function TSome(value) { | ||
classCallCheck(this, TSome); | ||
return possibleConstructorReturn(this, (TSome.__proto__ || Object.getPrototypeOf(TSome)).call(this, value, false)); | ||
} | ||
return TSome; | ||
}(Option); | ||
function Some(value) { | ||
return new Option(value, false); | ||
return new TSome(value); | ||
} | ||
function emptyOptionRef() { | ||
var F = Option; | ||
return new F(null, true); | ||
} | ||
var TNone = function (_Option2) { | ||
inherits(TNone, _Option2); | ||
var None = emptyOptionRef(); | ||
function TNone() { | ||
classCallCheck(this, TNone); | ||
return possibleConstructorReturn(this, (TNone.__proto__ || Object.getPrototypeOf(TNone)).call(this, undefined, true)); | ||
} | ||
return TNone; | ||
}(Option); | ||
var None = new TNone(); | ||
var OptionModule = { | ||
equals: function equals$$1(x, y) { | ||
return x ? x.equals(y) : !y; | ||
}, | ||
map: function map(f, fa) { | ||
return fa.map(f); | ||
}, | ||
ap: function ap(ff, fa) { | ||
return fa.ap(ff); | ||
}, | ||
of: Option.pure, | ||
chain: function chain(f, fa) { | ||
return fa.flatMap(f); | ||
}, | ||
chainRec: function chainRec(f, a) { | ||
return Option.tailRecM(a, function (a) { | ||
return f(Either.left, Either.right, a); | ||
}); | ||
} | ||
}; | ||
fantasyLandRegister(Option, OptionModule, OptionModule); | ||
var Try = function () { | ||
function Try(_success, _failure, _isSuccess) { | ||
function Try(value, tag) { | ||
classCallCheck(this, Try); | ||
this._isSuccess = _isSuccess; | ||
if (_isSuccess) this._successRef = _success;else this._failureRef = _failure; | ||
this._isSuccess = tag === "success"; | ||
this.value = value; | ||
} | ||
@@ -884,4 +955,4 @@ | ||
value: function get$$1() { | ||
if (!this._isSuccess) throw this._failureRef; | ||
return this._successRef; | ||
if (!this._isSuccess) throw this.value; | ||
return this.value; | ||
} | ||
@@ -891,3 +962,3 @@ }, { | ||
value: function getOrElse(fallback) { | ||
return this._isSuccess ? this._successRef : fallback; | ||
return this._isSuccess ? this.value : fallback; | ||
} | ||
@@ -897,3 +968,3 @@ }, { | ||
value: function getOrElseL(thunk) { | ||
return this._isSuccess ? this._successRef : thunk(); | ||
return this._isSuccess ? this.value : thunk(); | ||
} | ||
@@ -903,3 +974,3 @@ }, { | ||
value: function orNull() { | ||
return this._isSuccess ? this._successRef : null; | ||
return this._isSuccess ? this.value : null; | ||
} | ||
@@ -909,3 +980,3 @@ }, { | ||
value: function orUndefined() { | ||
return this._isSuccess ? this._successRef : undefined; | ||
return this._isSuccess ? this.value : undefined; | ||
} | ||
@@ -927,3 +998,3 @@ }, { | ||
value: function failed() { | ||
return this._isSuccess ? Failure(new NoSuchElementError("try.failed()")) : Success(this._failureRef); | ||
return this._isSuccess ? Failure(new NoSuchElementError("try.failed()")) : Success(this.value); | ||
} | ||
@@ -933,3 +1004,3 @@ }, { | ||
value: function fold(failure, success) { | ||
return this._isSuccess ? success(this._successRef) : failure(this._failureRef); | ||
return this._isSuccess ? success(this.value) : failure(this.value); | ||
} | ||
@@ -941,4 +1012,4 @@ }, { | ||
try { | ||
if (p(this._successRef)) return this; | ||
return Failure(new NoSuchElementError("Predicate does not hold for " + this._successRef)); | ||
if (p(this.value)) return this; | ||
return Failure(new NoSuchElementError("Predicate does not hold for " + this.value)); | ||
} catch (e) { | ||
@@ -953,3 +1024,3 @@ return Failure(e); | ||
try { | ||
return f(this._successRef); | ||
return f(this.value); | ||
} catch (e) { | ||
@@ -965,8 +1036,17 @@ return Failure(e); | ||
}, { | ||
key: "ap", | ||
value: function ap(ff) { | ||
var _this7 = this; | ||
return ff.flatMap(function (f) { | ||
return _this7.map(f); | ||
}); | ||
} | ||
}, { | ||
key: "map", | ||
value: function map(f) { | ||
var _this = this; | ||
var _this8 = this; | ||
return this._isSuccess ? Try.of(function () { | ||
return f(_this._successRef); | ||
return f(_this8.value); | ||
}) : this; | ||
@@ -977,3 +1057,3 @@ } | ||
value: function forEach(cb) { | ||
if (this._isSuccess) cb(this._successRef); | ||
if (this._isSuccess) cb(this.value); | ||
} | ||
@@ -983,6 +1063,6 @@ }, { | ||
value: function recover(f) { | ||
var _this2 = this; | ||
var _this9 = this; | ||
return this._isSuccess ? this : Try.of(function () { | ||
return f(_this2._failureRef); | ||
return f(_this9.value); | ||
}); | ||
@@ -994,3 +1074,3 @@ } | ||
try { | ||
return this._isSuccess ? this : f(this._failureRef); | ||
return this._isSuccess ? this : f(this.value); | ||
} catch (e) { | ||
@@ -1003,3 +1083,3 @@ return Failure(e); | ||
value: function toOption() { | ||
return this._isSuccess ? Some(this._successRef) : None; | ||
return this._isSuccess ? Some(this.value) : None; | ||
} | ||
@@ -1009,3 +1089,3 @@ }, { | ||
value: function toEither() { | ||
return this._isSuccess ? Right(this._successRef) : Left(this._failureRef); | ||
return this._isSuccess ? Right(this.value) : Left(this.value); | ||
} | ||
@@ -1016,3 +1096,3 @@ }, { | ||
if (that == null) return false; | ||
return this._isSuccess ? that._isSuccess && is(this._successRef, that._successRef) : !that._isSuccess && is(this._failureRef, that._failureRef); | ||
return this._isSuccess ? that._isSuccess && is(this.value, that.value) : !that._isSuccess && is(this.value, that.value); | ||
} | ||
@@ -1022,3 +1102,3 @@ }, { | ||
value: function hashCode$$1() { | ||
return this._isSuccess ? hashCode(this._successRef) : hashCode(this._failureRef); | ||
return this._isSuccess ? hashCode(this.value) : hashCode(this.value); | ||
} | ||
@@ -1065,3 +1145,3 @@ }], [{ | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef)); | ||
return Success(f(fa1.value, fa2.value)); | ||
} catch (e) { | ||
@@ -1078,3 +1158,3 @@ return Failure(e); | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef, fa3._successRef)); | ||
return Success(f(fa1.value, fa2.value, fa3.value)); | ||
} catch (e) { | ||
@@ -1092,3 +1172,3 @@ return Failure(e); | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef, fa3._successRef, fa4._successRef)); | ||
return Success(f(fa1.value, fa2.value, fa3.value, fa4.value)); | ||
} catch (e) { | ||
@@ -1107,3 +1187,3 @@ return Failure(e); | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef, fa3._successRef, fa4._successRef, fa5._successRef)); | ||
return Success(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value)); | ||
} catch (e) { | ||
@@ -1123,3 +1203,3 @@ return Failure(e); | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef, fa3._successRef, fa4._successRef, fa5._successRef, fa6._successRef)); | ||
return Success(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value, fa6.value)); | ||
} catch (e) { | ||
@@ -1138,4 +1218,4 @@ return Failure(e); | ||
var some = result.get(); | ||
if (some.isRight()) return Success(some.get()); | ||
cursor = some.swap().get(); | ||
if (some.isRight()) return Success(some.value); | ||
cursor = some.value; | ||
} catch (e) { | ||
@@ -1150,13 +1230,63 @@ return Failure(e); | ||
var TSuccess = function (_Try) { | ||
inherits(TSuccess, _Try); | ||
function TSuccess(value) { | ||
classCallCheck(this, TSuccess); | ||
return possibleConstructorReturn(this, (TSuccess.__proto__ || Object.getPrototypeOf(TSuccess)).call(this, value, "success")); | ||
} | ||
return TSuccess; | ||
}(Try); | ||
function Success(value) { | ||
return new Try(value, null, true); | ||
return new TSuccess(value); | ||
} | ||
var TFailure = function (_Try2) { | ||
inherits(TFailure, _Try2); | ||
function TFailure(value) { | ||
classCallCheck(this, TFailure); | ||
return possibleConstructorReturn(this, (TFailure.__proto__ || Object.getPrototypeOf(TFailure)).call(this, value, "failure")); | ||
} | ||
return TFailure; | ||
}(Try); | ||
function Failure(e) { | ||
return new Try(null, e, false); | ||
return new TFailure(e); | ||
} | ||
var TryModule = { | ||
equals: function equals$$1(x, y) { | ||
return x ? x.equals(y) : !y; | ||
}, | ||
map: function map(f, fa) { | ||
return fa.map(f); | ||
}, | ||
ap: function ap(ff, fa) { | ||
return fa.ap(ff); | ||
}, | ||
of: Try.pure, | ||
chain: function chain(f, fa) { | ||
return fa.flatMap(f); | ||
}, | ||
chainRec: function chainRec(f, a) { | ||
return Try.tailRecM(a, function (a) { | ||
return f(Either.left, Either.right, a); | ||
}); | ||
} | ||
}; | ||
fantasyLandRegister(Try, TryModule, TryModule); | ||
var tryUnitRef = Success(undefined); | ||
export { isValueObject, is, equals, hashCode, hashCodeOfString, id, applyMixins, CompositeError, DummyError, NoSuchElementError, IllegalInheritanceError, IllegalStateError, IllegalArgumentError, NotImplementedError, TimeoutError, Either, Left, Right, Option, Some, None, Try, Success, Failure }; | ||
export { internals as coreInternals, isValueObject, is, equals, universalSetoid, hashCode, hashCodeOfString, id, applyMixins, CompositeError, DummyError, NoSuchElementError, IllegalInheritanceError, IllegalStateError, IllegalArgumentError, NotImplementedError, TimeoutError, Either, TLeft, Left, TRight, Right, EitherModule, Option, TSome, Some, TNone, None, OptionModule, Try, TSuccess, Success, TFailure, Failure, TryModule }; | ||
//# sourceMappingURL=es5.js.map |
/*! | ||
* Copyright (c) 2017 by The Funfix Project Developers. | ||
* Copyright (c) 2017-2018 by The Funfix Project Developers. | ||
* Some rights reserved. | ||
@@ -17,4 +17,7 @@ * | ||
*/ | ||
export * from "./kinds"; | ||
export * from "./std"; | ||
export * from "./errors"; | ||
export * from "./disjunctions"; | ||
import * as coreInternals from "./internals"; | ||
export { coreInternals }; |
/*! | ||
* Copyright (c) 2017 by The Funfix Project Developers. | ||
* Copyright (c) 2017-2018 by The Funfix Project Developers. | ||
* Some rights reserved. | ||
@@ -17,6 +17,7 @@ * | ||
*/ | ||
// Exporting everything | ||
export * from "./std"; | ||
export * from "./errors"; | ||
export * from "./disjunctions"; | ||
import * as coreInternals from "./internals"; | ||
export { coreInternals }; | ||
//# sourceMappingURL=index.js.map |
/*! | ||
* Copyright (c) 2017 by The Funfix Project Developers. | ||
* Copyright (c) 2017-2018 by The Funfix Project Developers. | ||
* Some rights reserved. | ||
@@ -17,2 +17,3 @@ * | ||
*/ | ||
import { Setoid } from "funland"; | ||
/** | ||
@@ -86,2 +87,7 @@ * Interface for testing the equality of value objects. | ||
/** | ||
* Returns a `Setoid` type-class instance that depends | ||
* universal equality, as defined by {@link is}. | ||
*/ | ||
export declare const universalSetoid: Setoid<any>; | ||
/** | ||
* Universal hash-code function. | ||
@@ -88,0 +94,0 @@ * |
/*! | ||
* Copyright (c) 2017 by The Funfix Project Developers. | ||
* Copyright (c) 2017-2018 by The Funfix Project Developers. | ||
* Some rights reserved. | ||
@@ -82,2 +82,7 @@ * | ||
/** | ||
* Returns a `Setoid` type-class instance that depends | ||
* universal equality, as defined by {@link is}. | ||
*/ | ||
export const universalSetoid = { equals }; | ||
/** | ||
* Universal hash-code function. | ||
@@ -84,0 +89,0 @@ * |
581
dist/umd.js
@@ -37,2 +37,4 @@ (function (global, factory) { | ||
var universalSetoid = { equals: equals }; | ||
function hashCode(ref) { | ||
@@ -77,119 +79,2 @@ if (typeof ref === "number") { | ||
var asyncGenerator = function () { | ||
function AwaitValue(value) { | ||
this.value = value; | ||
} | ||
function AsyncGenerator(gen) { | ||
var front, back; | ||
function send(key, arg) { | ||
return new Promise(function (resolve, reject) { | ||
var request = { | ||
key: key, | ||
arg: arg, | ||
resolve: resolve, | ||
reject: reject, | ||
next: null | ||
}; | ||
if (back) { | ||
back = back.next = request; | ||
} else { | ||
front = back = request; | ||
resume(key, arg); | ||
} | ||
}); | ||
} | ||
function resume(key, arg) { | ||
try { | ||
var result = gen[key](arg); | ||
var value = result.value; | ||
if (value instanceof AwaitValue) { | ||
Promise.resolve(value.value).then(function (arg) { | ||
resume("next", arg); | ||
}, function (arg) { | ||
resume("throw", arg); | ||
}); | ||
} else { | ||
settle(result.done ? "return" : "normal", result.value); | ||
} | ||
} catch (err) { | ||
settle("throw", err); | ||
} | ||
} | ||
function settle(type, value) { | ||
switch (type) { | ||
case "return": | ||
front.resolve({ | ||
value: value, | ||
done: true | ||
}); | ||
break; | ||
case "throw": | ||
front.reject(value); | ||
break; | ||
default: | ||
front.resolve({ | ||
value: value, | ||
done: false | ||
}); | ||
break; | ||
} | ||
front = front.next; | ||
if (front) { | ||
resume(front.key, front.arg); | ||
} else { | ||
back = null; | ||
} | ||
} | ||
this._invoke = send; | ||
if (typeof gen.return !== "function") { | ||
this.return = undefined; | ||
} | ||
} | ||
if (typeof Symbol === "function" && Symbol.asyncIterator) { | ||
AsyncGenerator.prototype[Symbol.asyncIterator] = function () { | ||
return this; | ||
}; | ||
} | ||
AsyncGenerator.prototype.next = function (arg) { | ||
return this._invoke("next", arg); | ||
}; | ||
AsyncGenerator.prototype.throw = function (arg) { | ||
return this._invoke("throw", arg); | ||
}; | ||
AsyncGenerator.prototype.return = function (arg) { | ||
return this._invoke("return", arg); | ||
}; | ||
return { | ||
wrap: function (fn) { | ||
return function () { | ||
return new AsyncGenerator(fn.apply(this, arguments)); | ||
}; | ||
}, | ||
await: function (value) { | ||
return new AwaitValue(value); | ||
} | ||
}; | ||
}(); | ||
var classCallCheck = function (instance, Constructor) { | ||
@@ -455,8 +340,74 @@ if (!(instance instanceof Constructor)) { | ||
function convertToMethod(f) { | ||
return function () { | ||
var args = Array.prototype.slice.call(arguments); | ||
args.push(this); | ||
return f.apply(undefined, args); | ||
}; | ||
} | ||
function fantasyLandRegister(cls, monad, setoid) { | ||
var c = cls; | ||
var p = c.prototype; | ||
var fl = "fantasy-land/"; | ||
var equals = "equals"; | ||
var flEquals = fl + equals; | ||
var map = "map"; | ||
var flMap = fl + map; | ||
var ap = "ap"; | ||
var flAp = fl + ap; | ||
var flOf = fl + "of"; | ||
var chain = "chain"; | ||
var flChain = fl + chain; | ||
var chainRec = "chainRec"; | ||
var flChainRec = fl + chainRec; | ||
if (p[equals]) { | ||
p[flEquals] = p[equals]; | ||
} else { | ||
if (setoid) p[flEquals] = convertToMethod(setoid.equals); | ||
} | ||
if (p[map]) { | ||
p[flMap] = p[map]; | ||
} else { | ||
if (monad) p[flMap] = convertToMethod(monad.map); | ||
} | ||
if (p[ap]) { | ||
p[flAp] = p[ap]; | ||
} else { | ||
if (monad) p[flAp] = convertToMethod(monad.ap); | ||
} | ||
if (c["pure"]) { | ||
c[flOf] = c["pure"]; | ||
} else { | ||
if (monad) c[flOf] = monad.of; | ||
} | ||
if (p[chain]) { | ||
p[flChain] = p[chain]; | ||
} else { | ||
if (monad) p[flChain] = convertToMethod(monad.chain); | ||
} | ||
if (c[chainRec]) { | ||
c[flChainRec] = c[chainRec]; | ||
} else { | ||
if (monad) c[flChainRec] = monad.chainRec; | ||
} | ||
} | ||
var internals = Object.freeze({ | ||
convertToMethod: convertToMethod, | ||
fantasyLandRegister: fantasyLandRegister | ||
}); | ||
var Either = function () { | ||
function Either(_leftRef, _rightRef, _isRight) { | ||
function Either(value, tag) { | ||
classCallCheck(this, Either); | ||
this._isRight = _isRight; | ||
if (_isRight) this._rightRef = _rightRef;else this._leftRef = _leftRef; | ||
this._isRight = tag === "right"; | ||
this.value = value; | ||
} | ||
@@ -477,3 +428,3 @@ | ||
value: function contains(elem) { | ||
return this._isRight && is(this._rightRef, elem); | ||
return this._isRight && is(this.value, elem); | ||
} | ||
@@ -483,3 +434,3 @@ }, { | ||
value: function exists(p) { | ||
return this._isRight && p(this._rightRef); | ||
return this._isRight && p(this.value); | ||
} | ||
@@ -489,3 +440,3 @@ }, { | ||
value: function filterOrElse(p, zero) { | ||
return this._isRight ? p(this._rightRef) ? this : Left(zero()) : this; | ||
return this._isRight ? p(this.value) ? this : Left(zero()) : this; | ||
} | ||
@@ -495,8 +446,22 @@ }, { | ||
value: function flatMap(f) { | ||
return this._isRight ? f(this._rightRef) : this; | ||
return this._isRight ? f(this.value) : this; | ||
} | ||
}, { | ||
key: "chain", | ||
value: function chain(f) { | ||
return this.flatMap(f); | ||
} | ||
}, { | ||
key: "ap", | ||
value: function ap(ff) { | ||
var _this = this; | ||
return ff.flatMap(function (f) { | ||
return _this.map(f); | ||
}); | ||
} | ||
}, { | ||
key: "fold", | ||
value: function fold(left, right) { | ||
return this._isRight ? right(this._rightRef) : left(this._leftRef); | ||
return this._isRight ? right(this.value) : left(this.value); | ||
} | ||
@@ -506,3 +471,3 @@ }, { | ||
value: function forAll(p) { | ||
return !this._isRight || p(this._rightRef); | ||
return !this._isRight || p(this.value); | ||
} | ||
@@ -512,3 +477,3 @@ }, { | ||
value: function get$$1() { | ||
if (this._isRight) return this._rightRef; | ||
if (this._isRight) return this.value; | ||
throw new NoSuchElementError("left.get()"); | ||
@@ -519,3 +484,3 @@ } | ||
value: function getOrElse(fallback) { | ||
return this._isRight ? this._rightRef : fallback; | ||
return this._isRight ? this.value : fallback; | ||
} | ||
@@ -525,3 +490,3 @@ }, { | ||
value: function getOrElseL(thunk) { | ||
return this._isRight ? this._rightRef : thunk(); | ||
return this._isRight ? this.value : thunk(); | ||
} | ||
@@ -531,3 +496,3 @@ }, { | ||
value: function map(f) { | ||
return this._isRight ? Right(f(this._rightRef)) : this; | ||
return this._isRight ? Right(f(this.value)) : this; | ||
} | ||
@@ -537,3 +502,3 @@ }, { | ||
value: function forEach(cb) { | ||
if (this._isRight) cb(this._rightRef); | ||
if (this._isRight) cb(this.value); | ||
} | ||
@@ -543,3 +508,3 @@ }, { | ||
value: function swap() { | ||
return this._isRight ? Left(this._rightRef) : Right(this._leftRef); | ||
return this._isRight ? Left(this.value) : Right(this.value); | ||
} | ||
@@ -549,10 +514,9 @@ }, { | ||
value: function toOption() { | ||
return this._isRight ? Option.some(this._rightRef) : Option.none(); | ||
return this._isRight ? Some(this.value) : None; | ||
} | ||
}, { | ||
key: "equals", | ||
value: function equals$$1(other) { | ||
if (other == null) return false; | ||
if (this._isRight) return is(this._rightRef, other._rightRef); | ||
return is(this._leftRef, other._leftRef); | ||
value: function equals$$1(that) { | ||
if (that == null) return false; | ||
return this._isRight === that._isRight && is(this.value, that.value); | ||
} | ||
@@ -562,5 +526,10 @@ }, { | ||
value: function hashCode$$1() { | ||
return this._isRight ? hashCode(this._rightRef) << 2 : hashCode(this._leftRef) << 3; | ||
return this._isRight ? hashCode(this.value) << 2 : hashCode(this.value) << 3; | ||
} | ||
}], [{ | ||
key: "pure", | ||
value: function pure(value) { | ||
return new TRight(value); | ||
} | ||
}, { | ||
key: "left", | ||
@@ -580,3 +549,3 @@ value: function left(value) { | ||
if (fa2.isLeft()) return fa2; | ||
return Right(f(fa1._rightRef, fa2._rightRef)); | ||
return Right(f(fa1.value, fa2.value)); | ||
} | ||
@@ -589,3 +558,3 @@ }, { | ||
if (fa3.isLeft()) return fa3; | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef)); | ||
return Right(f(fa1.value, fa2.value, fa3.value)); | ||
} | ||
@@ -599,3 +568,3 @@ }, { | ||
if (fa4.isLeft()) return fa4; | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef, fa4._rightRef)); | ||
return Right(f(fa1.value, fa2.value, fa3.value, fa4.value)); | ||
} | ||
@@ -610,3 +579,3 @@ }, { | ||
if (fa5.isLeft()) return fa5; | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef, fa4._rightRef, fa5._rightRef)); | ||
return Right(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value)); | ||
} | ||
@@ -622,3 +591,3 @@ }, { | ||
if (fa6.isLeft()) return fa6; | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef, fa4._rightRef, fa5._rightRef, fa6._rightRef)); | ||
return Right(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value, fa6.value)); | ||
} | ||
@@ -631,6 +600,6 @@ }, { | ||
var result = f(cursor); | ||
if (result.isLeft()) return result; | ||
var some = result.get(); | ||
if (some.isRight()) return Right(some.get()); | ||
cursor = some.swap().get(); | ||
if (!result.isRight()) return result; | ||
var some = result.value; | ||
if (some.isRight()) return Right(some.value); | ||
cursor = some.value; | ||
} | ||
@@ -642,10 +611,60 @@ } | ||
var TLeft = function (_Either) { | ||
inherits(TLeft, _Either); | ||
function TLeft(value) { | ||
classCallCheck(this, TLeft); | ||
return possibleConstructorReturn(this, (TLeft.__proto__ || Object.getPrototypeOf(TLeft)).call(this, value, "left")); | ||
} | ||
return TLeft; | ||
}(Either); | ||
function Left(value) { | ||
return new Either(value, null, false); | ||
return new TLeft(value); | ||
} | ||
var TRight = function (_Either2) { | ||
inherits(TRight, _Either2); | ||
function TRight(value) { | ||
classCallCheck(this, TRight); | ||
return possibleConstructorReturn(this, (TRight.__proto__ || Object.getPrototypeOf(TRight)).call(this, value, "right")); | ||
} | ||
return TRight; | ||
}(Either); | ||
function Right(value) { | ||
return new Either(null, value, true); | ||
return new TRight(value); | ||
} | ||
var EitherModule = { | ||
equals: function equals$$1(x, y) { | ||
return x ? x.equals(y) : !y; | ||
}, | ||
map: function map(f, fa) { | ||
return fa.map(f); | ||
}, | ||
ap: function ap(ff, fa) { | ||
return fa.ap(ff); | ||
}, | ||
of: Either.pure, | ||
chain: function chain(f, fa) { | ||
return fa.flatMap(f); | ||
}, | ||
chainRec: function chainRec(f, a) { | ||
return Either.tailRecM(a, function (a) { | ||
return f(Either.left, Either.right, a); | ||
}); | ||
} | ||
}; | ||
fantasyLandRegister(Either, EitherModule, EitherModule); | ||
var Option = function () { | ||
@@ -656,3 +675,3 @@ function Option(ref, isEmpty) { | ||
this._isEmpty = isEmpty != null ? isEmpty : ref === null || ref === undefined; | ||
this._ref = ref; | ||
this.value = ref; | ||
} | ||
@@ -663,3 +682,4 @@ | ||
value: function get$$1() { | ||
if (!this._isEmpty) return this._ref;else throw new NoSuchElementError("Option.get"); | ||
if (!this._isEmpty) return this.value; | ||
throw new NoSuchElementError("Option.get"); | ||
} | ||
@@ -669,3 +689,3 @@ }, { | ||
value: function getOrElse(fallback) { | ||
if (!this._isEmpty) return this._ref;else return fallback; | ||
if (!this._isEmpty) return this.value;else return fallback; | ||
} | ||
@@ -675,3 +695,3 @@ }, { | ||
value: function orNull() { | ||
return !this._isEmpty ? this._ref : null; | ||
return !this._isEmpty ? this.value : null; | ||
} | ||
@@ -681,3 +701,3 @@ }, { | ||
value: function orUndefined() { | ||
return !this._isEmpty ? this._ref : undefined; | ||
return !this._isEmpty ? this.value : undefined; | ||
} | ||
@@ -687,3 +707,3 @@ }, { | ||
value: function getOrElseL(thunk) { | ||
if (!this._isEmpty) return this._ref;else return thunk(); | ||
if (!this._isEmpty) return this.value;else return thunk(); | ||
} | ||
@@ -713,13 +733,8 @@ }, { | ||
value: function map(f) { | ||
return this._isEmpty ? None : Some(f(this._ref)); | ||
return this._isEmpty ? None : Some(f(this.value)); | ||
} | ||
}, { | ||
key: "mapN", | ||
value: function mapN(f) { | ||
return this._isEmpty ? None : Option.of(f(this._ref)); | ||
} | ||
}, { | ||
key: "flatMap", | ||
value: function flatMap(f) { | ||
if (this._isEmpty) return None;else return f(this._ref); | ||
if (this._isEmpty) return None;else return f(this.value); | ||
} | ||
@@ -732,5 +747,14 @@ }, { | ||
}, { | ||
key: "ap", | ||
value: function ap(ff) { | ||
var _this4 = this; | ||
return ff.flatMap(function (f) { | ||
return _this4.map(f); | ||
}); | ||
} | ||
}, { | ||
key: "filter", | ||
value: function filter(p) { | ||
if (this._isEmpty || !p(this._ref)) return None;else return this; | ||
if (this._isEmpty || !p(this.value)) return None;else return this; | ||
} | ||
@@ -740,3 +764,4 @@ }, { | ||
value: function fold(fallback, f) { | ||
if (this._isEmpty) return fallback();else return f(this._ref); | ||
if (this._isEmpty) return fallback(); | ||
return f(this.value); | ||
} | ||
@@ -746,3 +771,3 @@ }, { | ||
value: function contains(elem) { | ||
return !this._isEmpty && is(this._ref, elem); | ||
return !this._isEmpty && is(this.value, elem); | ||
} | ||
@@ -752,3 +777,3 @@ }, { | ||
value: function exists(p) { | ||
return !this._isEmpty && p(this._ref); | ||
return !this._isEmpty && p(this.value); | ||
} | ||
@@ -758,3 +783,3 @@ }, { | ||
value: function forAll(p) { | ||
return this._isEmpty || p(this._ref); | ||
return this._isEmpty || p(this.value); | ||
} | ||
@@ -764,3 +789,3 @@ }, { | ||
value: function forEach(cb) { | ||
if (!this._isEmpty) cb(this._ref); | ||
if (!this._isEmpty) cb(this.value); | ||
} | ||
@@ -772,5 +797,3 @@ }, { | ||
if (this.nonEmpty() && that.nonEmpty()) { | ||
var l = this.get(); | ||
var r = that.get(); | ||
return is(l, r); | ||
return is(this.value, that.value); | ||
} | ||
@@ -782,3 +805,3 @@ return this.isEmpty() && that.isEmpty(); | ||
value: function hashCode$$1() { | ||
if (this._isEmpty) return 2433880;else if (this._ref == null) return 2433881 << 2;else return hashCode(this._ref) << 2; | ||
if (this._isEmpty) return 2433880;else if (this.value == null) return 2433881 << 2;else return hashCode(this.value) << 2; | ||
} | ||
@@ -813,3 +836,3 @@ }], [{ | ||
value: function map2(fa1, fa2, f) { | ||
return fa1.nonEmpty() && fa2.nonEmpty() ? Some(f(fa1.get(), fa2.get())) : None; | ||
return fa1.nonEmpty() && fa2.nonEmpty() ? Some(f(fa1.value, fa2.value)) : None; | ||
} | ||
@@ -819,3 +842,3 @@ }, { | ||
value: function map3(fa1, fa2, fa3, f) { | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() ? Some(f(fa1.get(), fa2.get(), fa3.get())) : None; | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() ? Some(f(fa1.value, fa2.value, fa3.value)) : None; | ||
} | ||
@@ -825,3 +848,3 @@ }, { | ||
value: function map4(fa1, fa2, fa3, fa4, f) { | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() ? Some(f(fa1.get(), fa2.get(), fa3.get(), fa4.get())) : None; | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() ? Some(f(fa1.value, fa2.value, fa3.value, fa4.value)) : None; | ||
} | ||
@@ -831,3 +854,3 @@ }, { | ||
value: function map5(fa1, fa2, fa3, fa4, fa5, f) { | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() && fa5.nonEmpty() ? Some(f(fa1.get(), fa2.get(), fa3.get(), fa4.get(), fa5.get())) : None; | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() && fa5.nonEmpty() ? Some(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value)) : None; | ||
} | ||
@@ -837,3 +860,3 @@ }, { | ||
value: function map6(fa1, fa2, fa3, fa4, fa5, fa6, f) { | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() && fa5.nonEmpty() && fa6.nonEmpty() ? Some(f(fa1.get(), fa2.get(), fa3.get(), fa4.get(), fa5.get(), fa6.get())) : None; | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() && fa5.nonEmpty() && fa6.nonEmpty() ? Some(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value, fa6.value)) : None; | ||
} | ||
@@ -846,6 +869,9 @@ }, { | ||
var result = f(cursor); | ||
if (result.isEmpty()) return None; | ||
var some = result.get(); | ||
if (some.isRight()) return Some(some.get()); | ||
cursor = some.swap().get(); | ||
if (result.nonEmpty()) { | ||
var some = result.value; | ||
if (some.isRight()) return Some(some.value); | ||
cursor = some.value; | ||
} else { | ||
return None; | ||
} | ||
} | ||
@@ -857,19 +883,64 @@ } | ||
var TSome = function (_Option) { | ||
inherits(TSome, _Option); | ||
function TSome(value) { | ||
classCallCheck(this, TSome); | ||
return possibleConstructorReturn(this, (TSome.__proto__ || Object.getPrototypeOf(TSome)).call(this, value, false)); | ||
} | ||
return TSome; | ||
}(Option); | ||
function Some(value) { | ||
return new Option(value, false); | ||
return new TSome(value); | ||
} | ||
function emptyOptionRef() { | ||
var F = Option; | ||
return new F(null, true); | ||
} | ||
var TNone = function (_Option2) { | ||
inherits(TNone, _Option2); | ||
var None = emptyOptionRef(); | ||
function TNone() { | ||
classCallCheck(this, TNone); | ||
return possibleConstructorReturn(this, (TNone.__proto__ || Object.getPrototypeOf(TNone)).call(this, undefined, true)); | ||
} | ||
return TNone; | ||
}(Option); | ||
var None = new TNone(); | ||
var OptionModule = { | ||
equals: function equals$$1(x, y) { | ||
return x ? x.equals(y) : !y; | ||
}, | ||
map: function map(f, fa) { | ||
return fa.map(f); | ||
}, | ||
ap: function ap(ff, fa) { | ||
return fa.ap(ff); | ||
}, | ||
of: Option.pure, | ||
chain: function chain(f, fa) { | ||
return fa.flatMap(f); | ||
}, | ||
chainRec: function chainRec(f, a) { | ||
return Option.tailRecM(a, function (a) { | ||
return f(Either.left, Either.right, a); | ||
}); | ||
} | ||
}; | ||
fantasyLandRegister(Option, OptionModule, OptionModule); | ||
var Try = function () { | ||
function Try(_success, _failure, _isSuccess) { | ||
function Try(value, tag) { | ||
classCallCheck(this, Try); | ||
this._isSuccess = _isSuccess; | ||
if (_isSuccess) this._successRef = _success;else this._failureRef = _failure; | ||
this._isSuccess = tag === "success"; | ||
this.value = value; | ||
} | ||
@@ -890,4 +961,4 @@ | ||
value: function get$$1() { | ||
if (!this._isSuccess) throw this._failureRef; | ||
return this._successRef; | ||
if (!this._isSuccess) throw this.value; | ||
return this.value; | ||
} | ||
@@ -897,3 +968,3 @@ }, { | ||
value: function getOrElse(fallback) { | ||
return this._isSuccess ? this._successRef : fallback; | ||
return this._isSuccess ? this.value : fallback; | ||
} | ||
@@ -903,3 +974,3 @@ }, { | ||
value: function getOrElseL(thunk) { | ||
return this._isSuccess ? this._successRef : thunk(); | ||
return this._isSuccess ? this.value : thunk(); | ||
} | ||
@@ -909,3 +980,3 @@ }, { | ||
value: function orNull() { | ||
return this._isSuccess ? this._successRef : null; | ||
return this._isSuccess ? this.value : null; | ||
} | ||
@@ -915,3 +986,3 @@ }, { | ||
value: function orUndefined() { | ||
return this._isSuccess ? this._successRef : undefined; | ||
return this._isSuccess ? this.value : undefined; | ||
} | ||
@@ -933,3 +1004,3 @@ }, { | ||
value: function failed() { | ||
return this._isSuccess ? Failure(new NoSuchElementError("try.failed()")) : Success(this._failureRef); | ||
return this._isSuccess ? Failure(new NoSuchElementError("try.failed()")) : Success(this.value); | ||
} | ||
@@ -939,3 +1010,3 @@ }, { | ||
value: function fold(failure, success) { | ||
return this._isSuccess ? success(this._successRef) : failure(this._failureRef); | ||
return this._isSuccess ? success(this.value) : failure(this.value); | ||
} | ||
@@ -947,4 +1018,4 @@ }, { | ||
try { | ||
if (p(this._successRef)) return this; | ||
return Failure(new NoSuchElementError("Predicate does not hold for " + this._successRef)); | ||
if (p(this.value)) return this; | ||
return Failure(new NoSuchElementError("Predicate does not hold for " + this.value)); | ||
} catch (e) { | ||
@@ -959,3 +1030,3 @@ return Failure(e); | ||
try { | ||
return f(this._successRef); | ||
return f(this.value); | ||
} catch (e) { | ||
@@ -971,8 +1042,17 @@ return Failure(e); | ||
}, { | ||
key: "ap", | ||
value: function ap(ff) { | ||
var _this7 = this; | ||
return ff.flatMap(function (f) { | ||
return _this7.map(f); | ||
}); | ||
} | ||
}, { | ||
key: "map", | ||
value: function map(f) { | ||
var _this = this; | ||
var _this8 = this; | ||
return this._isSuccess ? Try.of(function () { | ||
return f(_this._successRef); | ||
return f(_this8.value); | ||
}) : this; | ||
@@ -983,3 +1063,3 @@ } | ||
value: function forEach(cb) { | ||
if (this._isSuccess) cb(this._successRef); | ||
if (this._isSuccess) cb(this.value); | ||
} | ||
@@ -989,6 +1069,6 @@ }, { | ||
value: function recover(f) { | ||
var _this2 = this; | ||
var _this9 = this; | ||
return this._isSuccess ? this : Try.of(function () { | ||
return f(_this2._failureRef); | ||
return f(_this9.value); | ||
}); | ||
@@ -1000,3 +1080,3 @@ } | ||
try { | ||
return this._isSuccess ? this : f(this._failureRef); | ||
return this._isSuccess ? this : f(this.value); | ||
} catch (e) { | ||
@@ -1009,3 +1089,3 @@ return Failure(e); | ||
value: function toOption() { | ||
return this._isSuccess ? Some(this._successRef) : None; | ||
return this._isSuccess ? Some(this.value) : None; | ||
} | ||
@@ -1015,3 +1095,3 @@ }, { | ||
value: function toEither() { | ||
return this._isSuccess ? Right(this._successRef) : Left(this._failureRef); | ||
return this._isSuccess ? Right(this.value) : Left(this.value); | ||
} | ||
@@ -1022,3 +1102,3 @@ }, { | ||
if (that == null) return false; | ||
return this._isSuccess ? that._isSuccess && is(this._successRef, that._successRef) : !that._isSuccess && is(this._failureRef, that._failureRef); | ||
return this._isSuccess ? that._isSuccess && is(this.value, that.value) : !that._isSuccess && is(this.value, that.value); | ||
} | ||
@@ -1028,3 +1108,3 @@ }, { | ||
value: function hashCode$$1() { | ||
return this._isSuccess ? hashCode(this._successRef) : hashCode(this._failureRef); | ||
return this._isSuccess ? hashCode(this.value) : hashCode(this.value); | ||
} | ||
@@ -1071,3 +1151,3 @@ }], [{ | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef)); | ||
return Success(f(fa1.value, fa2.value)); | ||
} catch (e) { | ||
@@ -1084,3 +1164,3 @@ return Failure(e); | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef, fa3._successRef)); | ||
return Success(f(fa1.value, fa2.value, fa3.value)); | ||
} catch (e) { | ||
@@ -1098,3 +1178,3 @@ return Failure(e); | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef, fa3._successRef, fa4._successRef)); | ||
return Success(f(fa1.value, fa2.value, fa3.value, fa4.value)); | ||
} catch (e) { | ||
@@ -1113,3 +1193,3 @@ return Failure(e); | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef, fa3._successRef, fa4._successRef, fa5._successRef)); | ||
return Success(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value)); | ||
} catch (e) { | ||
@@ -1129,3 +1209,3 @@ return Failure(e); | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef, fa3._successRef, fa4._successRef, fa5._successRef, fa6._successRef)); | ||
return Success(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value, fa6.value)); | ||
} catch (e) { | ||
@@ -1144,4 +1224,4 @@ return Failure(e); | ||
var some = result.get(); | ||
if (some.isRight()) return Success(some.get()); | ||
cursor = some.swap().get(); | ||
if (some.isRight()) return Success(some.value); | ||
cursor = some.value; | ||
} catch (e) { | ||
@@ -1156,15 +1236,67 @@ return Failure(e); | ||
var TSuccess = function (_Try) { | ||
inherits(TSuccess, _Try); | ||
function TSuccess(value) { | ||
classCallCheck(this, TSuccess); | ||
return possibleConstructorReturn(this, (TSuccess.__proto__ || Object.getPrototypeOf(TSuccess)).call(this, value, "success")); | ||
} | ||
return TSuccess; | ||
}(Try); | ||
function Success(value) { | ||
return new Try(value, null, true); | ||
return new TSuccess(value); | ||
} | ||
var TFailure = function (_Try2) { | ||
inherits(TFailure, _Try2); | ||
function TFailure(value) { | ||
classCallCheck(this, TFailure); | ||
return possibleConstructorReturn(this, (TFailure.__proto__ || Object.getPrototypeOf(TFailure)).call(this, value, "failure")); | ||
} | ||
return TFailure; | ||
}(Try); | ||
function Failure(e) { | ||
return new Try(null, e, false); | ||
return new TFailure(e); | ||
} | ||
var TryModule = { | ||
equals: function equals$$1(x, y) { | ||
return x ? x.equals(y) : !y; | ||
}, | ||
map: function map(f, fa) { | ||
return fa.map(f); | ||
}, | ||
ap: function ap(ff, fa) { | ||
return fa.ap(ff); | ||
}, | ||
of: Try.pure, | ||
chain: function chain(f, fa) { | ||
return fa.flatMap(f); | ||
}, | ||
chainRec: function chainRec(f, a) { | ||
return Try.tailRecM(a, function (a) { | ||
return f(Either.left, Either.right, a); | ||
}); | ||
} | ||
}; | ||
fantasyLandRegister(Try, TryModule, TryModule); | ||
var tryUnitRef = Success(undefined); | ||
exports.coreInternals = internals; | ||
exports.isValueObject = isValueObject; | ||
exports.is = is; | ||
exports.equals = equals; | ||
exports.universalSetoid = universalSetoid; | ||
exports.hashCode = hashCode; | ||
@@ -1183,10 +1315,19 @@ exports.hashCodeOfString = hashCodeOfString; | ||
exports.Either = Either; | ||
exports.TLeft = TLeft; | ||
exports.Left = Left; | ||
exports.TRight = TRight; | ||
exports.Right = Right; | ||
exports.EitherModule = EitherModule; | ||
exports.Option = Option; | ||
exports.TSome = TSome; | ||
exports.Some = Some; | ||
exports.TNone = TNone; | ||
exports.None = None; | ||
exports.OptionModule = OptionModule; | ||
exports.Try = Try; | ||
exports.TSuccess = TSuccess; | ||
exports.Success = Success; | ||
exports.TFailure = TFailure; | ||
exports.Failure = Failure; | ||
exports.TryModule = TryModule; | ||
@@ -1193,0 +1334,0 @@ Object.defineProperty(exports, '__esModule', { value: true }); |
{ | ||
"name": "funfix-core", | ||
"description": "Sub-package of Funfix exposing primitive interfaces and data types belonging into a standard library", | ||
"version": "6.2.2", | ||
"version": "7.0.0-rc.2", | ||
"main": "dist/umd.js", | ||
@@ -10,3 +10,3 @@ "module": "dist/index.js", | ||
"scripts": { | ||
"lint": "flow check && tslint --type-check --project tsconfig.json -e **/node_modules/** -e **/dist/** -t codeFrame src/**/*.ts", | ||
"lint": "flow check && tslint --project tsconfig.json -e **/node_modules/** -e **/dist/** -t codeFrame src/**/*.ts", | ||
"doc": "../../scripts/generate-docs.js .", | ||
@@ -29,2 +29,5 @@ "clean": "rimraf dist && rimraf coverage && rimraf .nyc_output", | ||
], | ||
"dependencies": { | ||
"funland": "^0.1.4" | ||
}, | ||
"repository": { | ||
@@ -31,0 +34,0 @@ "type": "git", |
/*! | ||
* Copyright (c) 2017 by The Funfix Project Developers. | ||
* Copyright (c) 2017-2018 by The Funfix Project Developers. | ||
* Some rights reserved. | ||
@@ -18,4 +18,7 @@ * | ||
import { Setoid, Monad } from "funland" | ||
import * as std from "./std" | ||
import { HK, HK2 } from "./kinds" | ||
import { Throwable, NoSuchElementError } from "./errors" | ||
import { fantasyLandRegister } from "./internals" | ||
@@ -54,11 +57,9 @@ /** | ||
*/ | ||
export class Either<L, R> implements std.IEquals<Either<L, R>> { | ||
private _isRight: boolean | ||
private _rightRef: R | ||
private _leftRef: L | ||
export class Either<L, R> implements std.IEquals<Either<L, R>>, HK2<"funfix/either", L, R> { | ||
public readonly value: L | R | ||
private readonly _isRight: boolean | ||
private constructor(_leftRef: L, _rightRef: R, _isRight: boolean) { | ||
this._isRight = _isRight | ||
if (_isRight) this._rightRef = _rightRef | ||
else this._leftRef = _leftRef | ||
protected constructor(value: L | R, tag: "left" | "right") { | ||
this._isRight = tag === "right" | ||
this.value = value | ||
} | ||
@@ -74,3 +75,3 @@ | ||
*/ | ||
isLeft(): boolean { return !this._isRight } | ||
isLeft(): this is TLeft<L> { return !this._isRight } | ||
@@ -85,3 +86,3 @@ /** | ||
*/ | ||
isRight(): boolean { return this._isRight } | ||
isRight(): this is TRight<R> { return this._isRight } | ||
@@ -103,4 +104,4 @@ /** | ||
*/ | ||
contains(elem: R): boolean { | ||
return this._isRight && std.is(this._rightRef, elem) | ||
contains(elem: R): this is TRight<R> { | ||
return this._isRight && std.is(this.value, elem) | ||
} | ||
@@ -123,4 +124,4 @@ | ||
*/ | ||
exists(p: (r: R) => boolean): boolean { | ||
return this._isRight && p(this._rightRef) | ||
exists(p: (r: R) => boolean): this is TRight<R> { | ||
return this._isRight && p(this.value as R) | ||
} | ||
@@ -147,6 +148,6 @@ | ||
*/ | ||
filterOrElse(p: (r: R) => boolean, zero: () => L): Either<L, R> { | ||
filterOrElse<LL>(p: (r: R) => boolean, zero: () => LL): Either<L | LL, R> { | ||
return this._isRight | ||
? (p(this._rightRef) ? (this as any) : Left(zero())) | ||
: (this as any) | ||
? (p(this.value as R) ? this as any : Left(zero())) | ||
: this as any | ||
} | ||
@@ -161,6 +162,21 @@ | ||
flatMap<S>(f: (r: R) => Either<L, S>): Either<L, S> { | ||
return this._isRight ? f(this._rightRef) : (this as any) | ||
return this._isRight ? f(this.value as R) : (this as any) | ||
} | ||
/** Alias for [[flatMap]]. */ | ||
chain<S>(f: (r: R) => Either<L, S>): Either<L, S> { | ||
return this.flatMap(f) | ||
} | ||
/** | ||
* `Applicative` apply operator. | ||
* | ||
* Resembles {@link map}, but the passed mapping function is | ||
* lifted in the `Either` context. | ||
*/ | ||
ap<S>(ff: Either<L, (a: R) => S>): Either<L, S> { | ||
return ff.flatMap(f => this.map(f)) | ||
} | ||
/** | ||
* Applies the `left` function to [[Left]] values, and the | ||
@@ -181,3 +197,3 @@ * `right` function to [[Right]] values and returns the result. | ||
fold<S>(left: (l: L) => S, right: (r: R) => S): S { | ||
return this._isRight ? right(this._rightRef) : left(this._leftRef) | ||
return this._isRight ? right(this.value as R) : left(this.value as L) | ||
} | ||
@@ -202,3 +218,3 @@ | ||
forAll(p: (r: R) => boolean): boolean { | ||
return !this._isRight || p(this._rightRef) | ||
return !this._isRight || p(this.value as R) | ||
} | ||
@@ -218,3 +234,3 @@ | ||
get(): R { | ||
if (this._isRight) return this._rightRef | ||
if (this._isRight) return this.value as R | ||
throw new NoSuchElementError("left.get()") | ||
@@ -233,3 +249,3 @@ } | ||
getOrElse<RR>(fallback: RR): R | RR { | ||
return this._isRight ? this._rightRef : fallback | ||
return this._isRight ? this.value as R : fallback | ||
} | ||
@@ -247,3 +263,3 @@ | ||
getOrElseL<RR>(thunk: () => RR): R | RR { | ||
return this._isRight ? this._rightRef : thunk() | ||
return this._isRight ? this.value as R : thunk() | ||
} | ||
@@ -262,3 +278,3 @@ | ||
return this._isRight | ||
? Right(f(this._rightRef)) | ||
? Right(f(this.value as R)) | ||
: (this as any) | ||
@@ -277,3 +293,3 @@ } | ||
forEach(cb: (r: R) => void): void { | ||
if (this._isRight) cb(this._rightRef) | ||
if (this._isRight) cb(this.value as R) | ||
} | ||
@@ -292,4 +308,4 @@ | ||
return this._isRight | ||
? Left(this._rightRef) | ||
: Right(this._leftRef) | ||
? Left(this.value as R) | ||
: Right(this.value as L) | ||
} | ||
@@ -302,13 +318,14 @@ | ||
toOption(): Option<R> { | ||
return this._isRight | ||
? Option.some(this._rightRef) | ||
: Option.none() | ||
return this._isRight ? Some(this.value as R) : None | ||
} | ||
/** Implements {@link IEquals.equals}. */ | ||
equals(other: Either<L, R>): boolean { | ||
/** | ||
* Implements {@link IEquals.equals}. | ||
* | ||
* @param that is the right hand side of the equality check | ||
*/ | ||
equals(that: Either<L, R>): boolean { | ||
// tslint:disable-next-line:strict-type-predicates | ||
if (other == null) return false | ||
if (this._isRight) return std.is(this._rightRef, other._rightRef) | ||
return std.is(this._leftRef, other._leftRef) | ||
if (that == null) return false | ||
return this._isRight === that._isRight && std.is(this.value, that.value) | ||
} | ||
@@ -319,13 +336,27 @@ | ||
return this._isRight | ||
? std.hashCode(this._rightRef) << 2 | ||
: std.hashCode(this._leftRef) << 3 | ||
? std.hashCode(this.value as R) << 2 | ||
: std.hashCode(this.value as L) << 3 | ||
} | ||
// Implements HK<F, A> | ||
/** @hidden */ readonly _funKindF: Either<L, any> | ||
/** @hidden */ readonly _funKindA: R | ||
/** @hidden */ readonly _URI!: "funfix/either" | ||
/** @hidden */ readonly _A!: R | ||
/** @hidden */ readonly _L!: L | ||
// Implements Constructor<T> | ||
/** @hidden */ static readonly _funErasure: Either<any, any> | ||
/** @hidden */ static readonly _Class: Either<any, any> | ||
/** | ||
* Builds a pure `Either` value. | ||
* | ||
* This operation is the pure `Applicative` operation for lifting | ||
* a value in the `Either` context. | ||
*/ | ||
static pure<A>(value: A): Either<never, A> { | ||
return new TRight(value) | ||
} | ||
/** | ||
* Builds a left value, equivalent with {@link Left}. | ||
*/ | ||
static left<L, R>(value: L): Either<L, R> { | ||
@@ -335,2 +366,5 @@ return Left(value) | ||
/** | ||
* Builds a right value, equivalent with {@link Right}. | ||
*/ | ||
static right<L, R>(value: R): Either<L, R> { | ||
@@ -359,8 +393,9 @@ return Right(value) | ||
*/ | ||
static map2<A1,A2,L,R>(fa1: Either<L,A1>, fa2: Either<L,A2>, | ||
f: (a1: A1, a2: A2) => R): Either<L, R> { | ||
static map2<A1, A2, L, R>( | ||
fa1: Either<L,A1>, fa2: Either<L,A2>, | ||
f: (a1: A1, a2: A2) => R): Either<L, R> { | ||
if (fa1.isLeft()) return ((fa1 as any) as Either<L, R>) | ||
if (fa2.isLeft()) return ((fa2 as any) as Either<L, R>) | ||
return Right(f(fa1._rightRef, fa2._rightRef)) | ||
if (fa1.isLeft()) return fa1 | ||
if (fa2.isLeft()) return fa2 | ||
return Right(f(fa1.value as A1, fa2.value as A2)) | ||
} | ||
@@ -385,10 +420,10 @@ | ||
*/ | ||
static map3<A1,A2,A3,L,R>( | ||
fa1: Either<L,A1>, fa2: Either<L,A2>, fa3: Either<L,A3>, | ||
static map3<A1, A2, A3, L, R>( | ||
fa1: Either<L, A1>, fa2: Either<L, A2>, fa3: Either<L, A3>, | ||
f: (a1: A1, a2: A2, a3: A3) => R): Either<L, R> { | ||
if (fa1.isLeft()) return ((fa1 as any) as Either<L, R>) | ||
if (fa2.isLeft()) return ((fa2 as any) as Either<L, R>) | ||
if (fa3.isLeft()) return ((fa3 as any) as Either<L, R>) | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef)) | ||
if (fa1.isLeft()) return fa1 | ||
if (fa2.isLeft()) return fa2 | ||
if (fa3.isLeft()) return fa3 | ||
return Right(f(fa1.value as A1, fa2.value as A2, fa3.value as A3)) | ||
} | ||
@@ -413,11 +448,11 @@ | ||
*/ | ||
static map4<A1,A2,A3,A4,L,R>( | ||
static map4<A1, A2, A3, A4, L, R>( | ||
fa1: Either<L,A1>, fa2: Either<L,A2>, fa3: Either<L,A3>, fa4: Either<L,A4>, | ||
f: (a1: A1, a2: A2, a3: A3, a4: A4) => R): Either<L, R> { | ||
if (fa1.isLeft()) return ((fa1 as any) as Either<L, R>) | ||
if (fa2.isLeft()) return ((fa2 as any) as Either<L, R>) | ||
if (fa3.isLeft()) return ((fa3 as any) as Either<L, R>) | ||
if (fa4.isLeft()) return ((fa4 as any) as Either<L, R>) | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef, fa4._rightRef)) | ||
if (fa1.isLeft()) return fa1 | ||
if (fa2.isLeft()) return fa2 | ||
if (fa3.isLeft()) return fa3 | ||
if (fa4.isLeft()) return fa4 | ||
return Right(f(fa1.value as A1, fa2.value as A2, fa3.value as A3, fa4.value as A4)) | ||
} | ||
@@ -442,12 +477,12 @@ | ||
*/ | ||
static map5<A1,A2,A3,A4,A5,L,R>( | ||
static map5<A1, A2, A3, A4, A5, L, R>( | ||
fa1: Either<L,A1>, fa2: Either<L,A2>, fa3: Either<L,A3>, fa4: Either<L,A4>, fa5: Either<L,A5>, | ||
f: (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => R): Either<L, R> { | ||
if (fa1.isLeft()) return ((fa1 as any) as Either<L, R>) | ||
if (fa2.isLeft()) return ((fa2 as any) as Either<L, R>) | ||
if (fa3.isLeft()) return ((fa3 as any) as Either<L, R>) | ||
if (fa4.isLeft()) return ((fa4 as any) as Either<L, R>) | ||
if (fa5.isLeft()) return ((fa5 as any) as Either<L, R>) | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef, fa4._rightRef, fa5._rightRef)) | ||
if (fa1.isLeft()) return fa1 | ||
if (fa2.isLeft()) return fa2 | ||
if (fa3.isLeft()) return fa3 | ||
if (fa4.isLeft()) return fa4 | ||
if (fa5.isLeft()) return fa5 | ||
return Right(f(fa1.value as A1, fa2.value as A2, fa3.value as A3, fa4.value as A4, fa5.value as A5)) | ||
} | ||
@@ -472,13 +507,13 @@ | ||
*/ | ||
static map6<A1,A2,A3,A4,A5,A6,L,R>( | ||
static map6<A1, A2, A3, A4, A5, A6, L, R>( | ||
fa1: Either<L,A1>, fa2: Either<L,A2>, fa3: Either<L,A3>, fa4: Either<L,A4>, fa5: Either<L,A5>, fa6: Either<L,A6>, | ||
f: (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6) => R): Either<L, R> { | ||
if (fa1.isLeft()) return ((fa1 as any) as Either<L, R>) | ||
if (fa2.isLeft()) return ((fa2 as any) as Either<L, R>) | ||
if (fa3.isLeft()) return ((fa3 as any) as Either<L, R>) | ||
if (fa4.isLeft()) return ((fa4 as any) as Either<L, R>) | ||
if (fa5.isLeft()) return ((fa5 as any) as Either<L, R>) | ||
if (fa6.isLeft()) return ((fa6 as any) as Either<L, R>) | ||
return Right(f(fa1._rightRef, fa2._rightRef, fa3._rightRef, fa4._rightRef, fa5._rightRef, fa6._rightRef)) | ||
if (fa1.isLeft()) return fa1 | ||
if (fa2.isLeft()) return fa2 | ||
if (fa3.isLeft()) return fa3 | ||
if (fa4.isLeft()) return fa4 | ||
if (fa5.isLeft()) return fa5 | ||
if (fa6.isLeft()) return fa6 | ||
return Right(f(fa1.value as A1, fa2.value as A2, fa3.value as A3, fa4.value as A4, fa5.value as A5, fa6.value as A6)) | ||
} | ||
@@ -498,7 +533,7 @@ | ||
const result = f(cursor) | ||
if (result.isLeft()) return result as any | ||
if (!result.isRight()) return result as any | ||
const some = result.get() | ||
if (some.isRight()) return Right(some.get()) | ||
cursor = some.swap().get() | ||
const some = result.value | ||
if (some.isRight()) return Right(some.value) | ||
cursor = some.value as A | ||
} | ||
@@ -509,18 +544,73 @@ } | ||
/** | ||
* Result of the [[Left]] data constructor, representing | ||
* "left" values in the [[Either]] disjunction. | ||
* | ||
* @final | ||
*/ | ||
export class TLeft<L> extends Either<L, never> { | ||
public readonly value!: L | ||
constructor(value: L) { super(value, "left") } | ||
} | ||
/** | ||
* The `Left` data constructor represents the left side of the | ||
* [[Either]] disjoint union, as opposed to the [[Right]] side. | ||
*/ | ||
export function Left<L>(value: L): Either<L, never> { | ||
return new (Either as any)(value, null as never, false) | ||
export function Left<L>(value: L): TLeft<L> { | ||
return new TLeft(value) | ||
} | ||
/** | ||
* Result of the [[Right]] data constructor, representing | ||
* "right" values in the [[Either]] disjunction. | ||
* | ||
* @final | ||
*/ | ||
export class TRight<R> extends Either<never, R> { | ||
public readonly value!: R | ||
constructor(value: R) { super(value, "right") } | ||
} | ||
/** | ||
* The `Right` data constructor represents the right side of the | ||
* [[Either]] disjoint union, as opposed to the [[Left]] side. | ||
*/ | ||
export function Right<R>(value: R): Either<never, R> { | ||
return new (Either as any)(null as never, value, true) | ||
export function Right<R>(value: R): TRight<R> { | ||
return new TRight(value) | ||
} | ||
/** | ||
* Type enumerating the type-classes that `Either` implements. | ||
*/ | ||
export type EitherTypes = Setoid<Either<any, any>> & Monad<"funfix/either"> | ||
/** | ||
* Type-class implementations, compatible with the `static-land` | ||
* and `funland` specifications. | ||
* | ||
* See [funland-js.org](https://funland-js.org). | ||
*/ | ||
export const EitherModule: EitherTypes = { | ||
// Setoid | ||
equals: (x, y) => x ? x.equals(y) : !y, | ||
// Functor | ||
map: <L, A, B>(f: (a: A) => B, fa: Either<L, A>) => | ||
fa.map(f), | ||
// Apply | ||
ap: <L, A, B>(ff: Either<L, (a: A) => B>, fa: Either<L, A>): Either<L, B> => | ||
fa.ap(ff), | ||
// Applicative | ||
of: Either.pure, | ||
// Chain | ||
chain: <L, A, B>(f: (a: A) => Either<L, B>, fa: Either<L, A>): Either<L, B> => | ||
fa.flatMap(f), | ||
// ChainRec | ||
chainRec: <L, A, B>(f: <C>(next: (a: A) => C, done: (b: B) => C, a: A) => Either<L, C>, a: A): Either<L, B> => | ||
Either.tailRecM(a, a => f(Either.left as any, Either.right as any, a)) | ||
} | ||
// Registers Fantasy-Land compatible symbols | ||
fantasyLandRegister(Either, EitherModule, EitherModule) | ||
/** | ||
* Represents optional values, inspired by Scala's `Option` and by | ||
@@ -539,11 +629,11 @@ * Haskell's `Maybe` data types. | ||
*/ | ||
export class Option<A> implements std.IEquals<Option<A>> { | ||
export class Option<A> implements std.IEquals<Option<A>>, HK<"funfix/option", A> { | ||
// tslint:disable-next-line:variable-name | ||
private _isEmpty: boolean | ||
private _ref: A | ||
private readonly _isEmpty: boolean | ||
public readonly value: undefined | A | ||
private constructor(ref: A, isEmpty?: boolean) { | ||
protected constructor(ref: A | undefined, isEmpty?: boolean) { | ||
/* tslint:disable-next-line:strict-type-predicates */ | ||
this._isEmpty = isEmpty != null ? isEmpty : (ref === null || ref === undefined) | ||
this._ref = ref | ||
this.value = ref | ||
} | ||
@@ -562,4 +652,4 @@ | ||
get(): A { | ||
if (!this._isEmpty) return this._ref | ||
else throw new NoSuchElementError("Option.get") | ||
if (!this._isEmpty) return this.value as A | ||
throw new NoSuchElementError("Option.get") | ||
} | ||
@@ -574,3 +664,3 @@ | ||
getOrElse<AA>(fallback: AA): A | AA { | ||
if (!this._isEmpty) return this._ref | ||
if (!this._isEmpty) return this.value as A | ||
else return fallback | ||
@@ -585,3 +675,3 @@ } | ||
orNull(): A | null { | ||
return !this._isEmpty ? this._ref : null | ||
return !this._isEmpty ? this.value as A : null | ||
} | ||
@@ -594,3 +684,3 @@ | ||
orUndefined(): A | undefined { | ||
return !this._isEmpty ? this._ref : undefined | ||
return !this._isEmpty ? this.value : undefined | ||
} | ||
@@ -605,3 +695,3 @@ | ||
getOrElseL<AA>(thunk: () => AA): A | AA { | ||
if (!this._isEmpty) return this._ref | ||
if (!this._isEmpty) return this.value as A | ||
else return thunk() | ||
@@ -634,3 +724,3 @@ } | ||
*/ | ||
isEmpty(): boolean { return this._isEmpty } | ||
isEmpty(): this is TNone { return this._isEmpty } | ||
@@ -640,3 +730,3 @@ /** | ||
*/ | ||
nonEmpty(): boolean { return !this._isEmpty } | ||
nonEmpty(): this is TSome<A> { return !this._isEmpty } | ||
@@ -657,36 +747,6 @@ /** | ||
map<B>(f: (a: A) => B): Option<B> { | ||
return this._isEmpty ? None : Some(f(this._ref)) | ||
return this._isEmpty ? None : Some(f(this.value as A)) | ||
} | ||
/** | ||
* Returns an optioning containing the result of the source mapped | ||
* by the given function `f`. | ||
* | ||
* Similar to `map`, except that if the mapping function `f` returns | ||
* `null`, then the final result returned will be [[Option.none]]. | ||
* | ||
* Comparison: | ||
* | ||
* ```typescript | ||
* Option.of(1).mapN(x => null) // None | ||
* Option.of(1).map(x => null) // Some(null) | ||
* | ||
* Option.of(1).mapN(x => x+1) // 2 | ||
* Option.of(1).map(x => x+1) // 2 | ||
* ``` | ||
* | ||
* What this operation does is to allow for safe chaining of multiple | ||
* method calls or functions that might produce `null` results: | ||
* | ||
* ```typescript | ||
* Option.of(user) | ||
* .mapN(_ => _.contacts) | ||
* .mapN(_ => _.length) | ||
* ``` | ||
*/ | ||
mapN<B>(f: (a: A) => B | null | undefined): Option<B> { | ||
return this._isEmpty ? None : Option.of(f(this._ref)) | ||
} | ||
/** | ||
* Returns the result of applying `f` to this option's value if | ||
@@ -720,3 +780,3 @@ * the option is nonempty, otherwise returns an empty option. | ||
if (this._isEmpty) return None | ||
else return f(this._ref) | ||
else return f(this.value as A) | ||
} | ||
@@ -730,2 +790,12 @@ | ||
/** | ||
* `Applicative` apply operator. | ||
* | ||
* Resembles {@link map}, but the passed mapping function is | ||
* lifted in the `Either` context. | ||
*/ | ||
ap<B>(ff: Option<(a: A) => B>): Option<B> { | ||
return ff.flatMap(f => this.map(f)) | ||
} | ||
/** | ||
* Returns this option if it is nonempty AND applying the | ||
@@ -741,4 +811,6 @@ * predicate `p` to the underlying value yields `true`, | ||
*/ | ||
filter<B extends A>(p: (a: A) => a is B): Option<B> | ||
filter(p: (a: A) => boolean): Option<A> | ||
filter(p: (a: A) => boolean): Option<A> { | ||
if (this._isEmpty || !p(this._ref)) return None | ||
if (this._isEmpty || !p(this.value as A)) return None | ||
else return this | ||
@@ -766,3 +838,3 @@ } | ||
if (this._isEmpty) return fallback() | ||
else return f(this._ref) | ||
return f(this.value as A) | ||
} | ||
@@ -775,3 +847,3 @@ | ||
contains(elem: A): boolean { | ||
return !this._isEmpty && std.is(this._ref, elem) | ||
return !this._isEmpty && std.is(this.value, elem) | ||
} | ||
@@ -786,3 +858,3 @@ | ||
exists(p: (a: A) => boolean): boolean { | ||
return !this._isEmpty && p(this._ref) | ||
return !this._isEmpty && p(this.value as A) | ||
} | ||
@@ -797,3 +869,3 @@ | ||
forAll(p: (a: A) => boolean): boolean { | ||
return this._isEmpty || p(this._ref) | ||
return this._isEmpty || p(this.value as A) | ||
} | ||
@@ -808,6 +880,10 @@ | ||
forEach(cb: (a: A) => void): void { | ||
if (!this._isEmpty) cb(this._ref) | ||
if (!this._isEmpty) cb(this.value as A) | ||
} | ||
// Implemented from IEquals | ||
/** | ||
* Implements {@link IEquals.equals}. | ||
* | ||
* @param that is the right hand side of the equality check | ||
*/ | ||
equals(that: Option<A>): boolean { | ||
@@ -817,5 +893,3 @@ // tslint:disable-next-line:strict-type-predicates | ||
if (this.nonEmpty() && that.nonEmpty()) { | ||
const l = this.get() | ||
const r = that.get() | ||
return std.is(l, r) | ||
return std.is(this.value, that.value) | ||
} | ||
@@ -828,12 +902,13 @@ return this.isEmpty() && that.isEmpty() | ||
if (this._isEmpty) return 2433880 | ||
else if (this._ref == null) return 2433881 << 2 | ||
else return std.hashCode(this._ref) << 2 | ||
// tslint:disable-next-line:strict-type-predicates | ||
else if (this.value == null) return 2433881 << 2 | ||
else return std.hashCode(this.value) << 2 | ||
} | ||
// Implements HK<F, A> | ||
/** @hidden */ readonly _funKindF: Option<any> | ||
/** @hidden */ readonly _funKindA: A | ||
/** @hidden */ readonly _URI!: "funfix/option" | ||
/** @hidden */ readonly _A!: A | ||
// Implements Constructor<T> | ||
/** @hidden */ static readonly _funErasure: Option<any> | ||
/** @hidden */ static readonly _Class: Option<any> | ||
@@ -877,3 +952,3 @@ /** | ||
*/ | ||
static none(): Option<never> { | ||
static none<A = never>(): Option<A> { | ||
return None | ||
@@ -920,7 +995,8 @@ } | ||
*/ | ||
static map2<A1,A2,R>(fa1: Option<A1>, fa2: Option<A2>, | ||
f: (a1: A1, a2: A2) => R): Option<R> { | ||
static map2<A1,A2,R>( | ||
fa1: Option<A1>, fa2: Option<A2>, | ||
f: (a1: A1, a2: A2) => R): Option<R> { | ||
return fa1.nonEmpty() && fa2.nonEmpty() | ||
? Some(f(fa1.get(), fa2.get())) | ||
? Some(f(fa1.value, fa2.value)) | ||
: None | ||
@@ -946,7 +1022,8 @@ } | ||
*/ | ||
static map3<A1,A2,A3,R>(fa1: Option<A1>, fa2: Option<A2>, fa3: Option<A3>, | ||
f: (a1: A1, a2: A2, a3: A3) => R): Option<R> { | ||
static map3<A1,A2,A3,R>( | ||
fa1: Option<A1>, fa2: Option<A2>, fa3: Option<A3>, | ||
f: (a1: A1, a2: A2, a3: A3) => R): Option<R> { | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() | ||
? Some(f(fa1.get(), fa2.get(), fa3.get())) | ||
? Some(f(fa1.value, fa2.value, fa3.value)) | ||
: None | ||
@@ -977,3 +1054,3 @@ } | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() | ||
? Some(f(fa1.get(), fa2.get(), fa3.get(), fa4.get())) | ||
? Some(f(fa1.value, fa2.value, fa3.value, fa4.value)) | ||
: None | ||
@@ -1004,3 +1081,3 @@ } | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() && fa5.nonEmpty() | ||
? Some(f(fa1.get(), fa2.get(), fa3.get(), fa4.get(), fa5.get())) | ||
? Some(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value)) | ||
: None | ||
@@ -1031,3 +1108,3 @@ } | ||
return fa1.nonEmpty() && fa2.nonEmpty() && fa3.nonEmpty() && fa4.nonEmpty() && fa5.nonEmpty() && fa6.nonEmpty() | ||
? Some(f(fa1.get(), fa2.get(), fa3.get(), fa4.get(), fa5.get(), fa6.get())) | ||
? Some(f(fa1.value, fa2.value, fa3.value, fa4.value, fa5.value, fa6.value)) | ||
: None | ||
@@ -1048,7 +1125,9 @@ } | ||
const result = f(cursor) | ||
if (result.isEmpty()) return None | ||
const some = result.get() | ||
if (some.isRight()) return Some(some.get()) | ||
cursor = some.swap().get() | ||
if (result.nonEmpty()) { | ||
const some = result.value | ||
if (some.isRight()) return Some(some.value) | ||
cursor = some.value as A | ||
} else { | ||
return None | ||
} | ||
} | ||
@@ -1059,2 +1138,11 @@ } | ||
/** | ||
* Result of the [[Some]] data constructor, representing | ||
* non-empty values in the [[Option]] disjunction. | ||
*/ | ||
export class TSome<A> extends Option<A> { | ||
public readonly value!: A | ||
constructor(value: A) { super(value, false) } | ||
} | ||
/** | ||
* The `Some<A>` data constructor for [[Option]] represents existing | ||
@@ -1065,12 +1153,13 @@ * values of type `A`. | ||
*/ | ||
export function Some<A>(value: A): Option<A> { | ||
return new (Option as any)(value, false) | ||
export function Some<A>(value: A): TSome<A> { | ||
return new TSome(value) | ||
} | ||
/** @Hidden */ | ||
function emptyOptionRef() { | ||
// Ugly workaround to get around the limitation of | ||
// Option's private constructor | ||
const F: any = Option | ||
return new F(null, true) as Option<never> | ||
/** | ||
* Result of the [[Some]] data constructor, representing | ||
* non-empty values in the [[Option]] disjunction. | ||
*/ | ||
export class TNone extends Option<never> { | ||
public readonly value!: undefined | ||
private constructor() { super(undefined, true) } | ||
} | ||
@@ -1084,5 +1173,41 @@ | ||
*/ | ||
export const None: Option<never> = emptyOptionRef() | ||
export const None: TNone = | ||
new (TNone as any)() | ||
/** | ||
* Type enumerating the type classes implemented by `Option`. | ||
*/ | ||
export type OptionTypes = | ||
Setoid<Option<any>> & | ||
Monad<"funfix/option"> | ||
/** | ||
* Type-class implementations, compatible with the `static-land` | ||
* and `funland` specification. | ||
* | ||
* See [funland-js.org](https://funland-js.org). | ||
*/ | ||
export const OptionModule: OptionTypes = { | ||
// Setoid | ||
equals: (x, y) => x ? x.equals(y) : !y, | ||
// Functor | ||
map: <A, B>(f: (a: A) => B, fa: Option<A>) => | ||
fa.map(f), | ||
// Apply | ||
ap: <A, B>(ff: Option<(a: A) => B>, fa: Option<A>): Option<B> => | ||
fa.ap(ff), | ||
// Applicative | ||
of: Option.pure, | ||
// Chain | ||
chain: <A, B>(f: (a: A) => Option<B>, fa: Option<A>): Option<B> => | ||
fa.flatMap(f), | ||
// ChainRec | ||
chainRec: <A, B>(f: <C>(next: (a: A) => C, done: (b: B) => C, a: A) => Option<C>, a: A): Option<B> => | ||
Option.tailRecM(a, a => f(Either.left as any, Either.right as any, a)) | ||
} | ||
// Registers Fantasy-Land compatible symbols | ||
fantasyLandRegister(Option, OptionModule, OptionModule) | ||
/** | ||
* The `Try` type represents a computation that may either result in an | ||
@@ -1133,11 +1258,9 @@ * exception, or return a successfully computed value. It's similar to, | ||
*/ | ||
export class Try<A> implements std.IEquals<Try<A>> { | ||
export class Try<A> implements std.IEquals<Try<A>>, HK<"funfix/try", A> { | ||
private _isSuccess: boolean | ||
private _successRef: A | ||
private _failureRef: Throwable | ||
public readonly value: Throwable | A | ||
private constructor(_success: A, _failure: Throwable, _isSuccess: boolean) { | ||
this._isSuccess = _isSuccess | ||
if (_isSuccess) this._successRef = _success | ||
else this._failureRef = _failure | ||
protected constructor(value: Throwable | A, tag: "failure" | "success") { | ||
this._isSuccess = tag === "success" | ||
this.value = value | ||
} | ||
@@ -1149,3 +1272,3 @@ | ||
*/ | ||
isSuccess(): boolean { return this._isSuccess } | ||
isSuccess(): this is TSuccess<A> { return this._isSuccess } | ||
@@ -1156,3 +1279,3 @@ /** | ||
*/ | ||
isFailure(): boolean { return !this._isSuccess } | ||
isFailure(): this is TFailure { return !this._isSuccess } | ||
@@ -1169,4 +1292,4 @@ /** | ||
get(): A { | ||
if (!this._isSuccess) throw this._failureRef | ||
return this._successRef | ||
if (!this._isSuccess) throw this.value | ||
return this.value as A | ||
} | ||
@@ -1184,3 +1307,3 @@ | ||
getOrElse<AA>(fallback: AA): A | AA { | ||
return this._isSuccess ? this._successRef : fallback | ||
return this._isSuccess ? this.value as A : fallback | ||
} | ||
@@ -1198,3 +1321,3 @@ | ||
getOrElseL<AA>(thunk: () => AA): A | AA { | ||
return this._isSuccess ? this._successRef : thunk() | ||
return this._isSuccess ? this.value as A : thunk() | ||
} | ||
@@ -1218,3 +1341,3 @@ | ||
orNull(): A | null { | ||
return this._isSuccess ? this._successRef : null | ||
return this._isSuccess ? this.value as A : null | ||
} | ||
@@ -1238,3 +1361,3 @@ | ||
orUndefined(): A | undefined { | ||
return this._isSuccess ? this._successRef : undefined | ||
return this._isSuccess ? this.value as A : undefined | ||
} | ||
@@ -1279,3 +1402,3 @@ | ||
? Failure(new NoSuchElementError("try.failed()")) | ||
: Success(this._failureRef) | ||
: Success(this.value as Throwable) | ||
} | ||
@@ -1300,4 +1423,4 @@ | ||
return this._isSuccess | ||
? success(this._successRef) | ||
: failure(this._failureRef) | ||
? success(this.value as A) | ||
: failure(this.value as Throwable) | ||
} | ||
@@ -1311,9 +1434,11 @@ | ||
*/ | ||
filter<B extends A>(p: (a: A) => a is B): Try<B> | ||
filter(p: (a: A) => boolean): Try<A> | ||
filter(p: (a: A) => boolean): Try<A> { | ||
if (!this._isSuccess) return this | ||
try { | ||
if (p(this._successRef)) return this | ||
if (p(this.value as A)) return this | ||
return Failure( | ||
new NoSuchElementError( | ||
`Predicate does not hold for ${this._successRef}` | ||
`Predicate does not hold for ${this.value as A}` | ||
)) | ||
@@ -1342,3 +1467,3 @@ } catch (e) { | ||
try { | ||
return f(this._successRef) | ||
return f(this.value as A) | ||
} catch (e) { | ||
@@ -1355,2 +1480,12 @@ return Failure(e) | ||
/** | ||
* `Applicative` apply operator. | ||
* | ||
* Resembles {@link map}, but the passed mapping function is | ||
* lifted in the `Either` context. | ||
*/ | ||
ap<B>(ff: Try<(a: A) => B>): Try<B> { | ||
return ff.flatMap(f => this.map(f)) | ||
} | ||
/** | ||
* Returns a `Try` containing the result of applying `f` to | ||
@@ -1371,3 +1506,3 @@ * this option's value, but only if it's a `Success`, or | ||
return this._isSuccess | ||
? Try.of(() => f(this._successRef)) | ||
? Try.of(() => f(this.value as A)) | ||
: ((this as any) as Try<B>) | ||
@@ -1381,3 +1516,3 @@ } | ||
forEach(cb: (a: A) => void): void { | ||
if (this._isSuccess) cb(this._successRef) | ||
if (this._isSuccess) cb(this.value as A) | ||
} | ||
@@ -1406,3 +1541,5 @@ | ||
recover<AA>(f: (error: Throwable) => AA): Try<A | AA> { | ||
return this._isSuccess ? this : Try.of(() => f(this._failureRef)) | ||
return this._isSuccess | ||
? this | ||
: Try.of(() => f(this.value as Throwable)) | ||
} | ||
@@ -1432,3 +1569,3 @@ | ||
try { | ||
return this._isSuccess ? this : f(this._failureRef) | ||
return this._isSuccess ? this : f(this.value as Throwable) | ||
} catch (e) { | ||
@@ -1452,3 +1589,3 @@ return Failure(e) | ||
toOption(): Option<A> { | ||
return this._isSuccess ? Some(this._successRef) : None | ||
return this._isSuccess ? Some(this.value as A) : None | ||
} | ||
@@ -1470,7 +1607,9 @@ | ||
return this._isSuccess | ||
? Right(this._successRef) | ||
: Left(this._failureRef) | ||
? Right(this.value as A) | ||
: Left(this.value as Throwable) | ||
} | ||
// Implemented from IEquals | ||
/** | ||
* Implements {@link IEquals.equals} with overridable equality for `A`. | ||
*/ | ||
equals(that: Try<A>): boolean { | ||
@@ -1480,4 +1619,4 @@ // tslint:disable-next-line:strict-type-predicates | ||
return this._isSuccess | ||
? that._isSuccess && std.is(this._successRef, that._successRef) | ||
: !that._isSuccess && std.is(this._failureRef, that._failureRef) | ||
? that._isSuccess && std.is(this.value as A, that.value as A) | ||
: !that._isSuccess && std.is(this.value, that.value) | ||
} | ||
@@ -1488,12 +1627,12 @@ | ||
return this._isSuccess | ||
? std.hashCode(this._successRef) | ||
: std.hashCode(this._failureRef) | ||
? std.hashCode(this.value as A) | ||
: std.hashCode(this.value as Throwable) | ||
} | ||
// Implements HK<F, A> | ||
/** @hidden */ readonly _funKindF: Try<any> | ||
/** @hidden */ readonly _funKindA: A | ||
/** @hidden */ readonly _URI!: "funfix/try" | ||
/** @hidden */ readonly _A!: A | ||
// Implements Constructor<T> | ||
/** @hidden */ static readonly _funErasure: Try<any> | ||
/** @hidden */ static readonly _Class: Try<any> | ||
@@ -1582,6 +1721,6 @@ /** | ||
if (fa1.isFailure()) return ((fa1 as any) as Try<R>) | ||
if (fa2.isFailure()) return ((fa2 as any) as Try<R>) | ||
if (fa1.isFailure()) return fa1 | ||
if (fa2.isFailure()) return fa2 | ||
try { | ||
return Success(f(fa1._successRef, fa2._successRef)) | ||
return Success(f(fa1.value as A1, fa2.value as A2)) | ||
} catch (e) { | ||
@@ -1621,10 +1760,11 @@ return Failure(e) | ||
if (fa1.isFailure()) return ((fa1 as any) as Try<R>) | ||
if (fa2.isFailure()) return ((fa2 as any) as Try<R>) | ||
if (fa3.isFailure()) return ((fa3 as any) as Try<R>) | ||
if (fa1.isFailure()) return fa1 | ||
if (fa2.isFailure()) return fa2 | ||
if (fa3.isFailure()) return fa3 | ||
try { | ||
return Success(f( | ||
fa1._successRef, | ||
fa2._successRef, | ||
fa3._successRef)) | ||
fa1.value as A1, | ||
fa2.value as A2, | ||
fa3.value as A3 | ||
)) | ||
} catch (e) { | ||
@@ -1665,12 +1805,13 @@ return Failure(e) | ||
if (fa1.isFailure()) return ((fa1 as any) as Try<R>) | ||
if (fa2.isFailure()) return ((fa2 as any) as Try<R>) | ||
if (fa3.isFailure()) return ((fa3 as any) as Try<R>) | ||
if (fa4.isFailure()) return ((fa4 as any) as Try<R>) | ||
if (fa1.isFailure()) return fa1 | ||
if (fa2.isFailure()) return fa2 | ||
if (fa3.isFailure()) return fa3 | ||
if (fa4.isFailure()) return fa4 | ||
try { | ||
return Success(f( | ||
fa1._successRef, | ||
fa2._successRef, | ||
fa3._successRef, | ||
fa4._successRef)) | ||
fa1.value as A1, | ||
fa2.value as A2, | ||
fa3.value as A3, | ||
fa4.value as A4 | ||
)) | ||
} catch (e) { | ||
@@ -1718,14 +1859,15 @@ return Failure(e) | ||
if (fa1.isFailure()) return ((fa1 as any) as Try<R>) | ||
if (fa2.isFailure()) return ((fa2 as any) as Try<R>) | ||
if (fa3.isFailure()) return ((fa3 as any) as Try<R>) | ||
if (fa4.isFailure()) return ((fa4 as any) as Try<R>) | ||
if (fa5.isFailure()) return ((fa5 as any) as Try<R>) | ||
if (fa1.isFailure()) return fa1 | ||
if (fa2.isFailure()) return fa2 | ||
if (fa3.isFailure()) return fa3 | ||
if (fa4.isFailure()) return fa4 | ||
if (fa5.isFailure()) return fa5 | ||
try { | ||
return Success(f( | ||
fa1._successRef, | ||
fa2._successRef, | ||
fa3._successRef, | ||
fa4._successRef, | ||
fa5._successRef)) | ||
fa1.value as A1, | ||
fa2.value as A2, | ||
fa3.value as A3, | ||
fa4.value as A4, | ||
fa5.value as A5 | ||
)) | ||
} catch (e) { | ||
@@ -1775,16 +1917,17 @@ return Failure(e) | ||
if (fa1.isFailure()) return ((fa1 as any) as Try<R>) | ||
if (fa2.isFailure()) return ((fa2 as any) as Try<R>) | ||
if (fa3.isFailure()) return ((fa3 as any) as Try<R>) | ||
if (fa4.isFailure()) return ((fa4 as any) as Try<R>) | ||
if (fa5.isFailure()) return ((fa5 as any) as Try<R>) | ||
if (fa6.isFailure()) return ((fa6 as any) as Try<R>) | ||
if (fa1.isFailure()) return fa1 | ||
if (fa2.isFailure()) return fa2 | ||
if (fa3.isFailure()) return fa3 | ||
if (fa4.isFailure()) return fa4 | ||
if (fa5.isFailure()) return fa5 | ||
if (fa6.isFailure()) return fa6 | ||
try { | ||
return Success(f( | ||
fa1._successRef, | ||
fa2._successRef, | ||
fa3._successRef, | ||
fa4._successRef, | ||
fa5._successRef, | ||
fa6._successRef)) | ||
fa1.value as A1, | ||
fa2.value as A2, | ||
fa3.value as A3, | ||
fa4.value as A4, | ||
fa5.value as A5, | ||
fa6.value as A6 | ||
)) | ||
} catch (e) { | ||
@@ -1811,4 +1954,4 @@ return Failure(e) | ||
const some = result.get() | ||
if (some.isRight()) return Success(some.get()) | ||
cursor = some.swap().get() | ||
if (some.isRight()) return Success(some.value) | ||
cursor = some.value as A | ||
} catch (e) { | ||
@@ -1822,2 +1965,13 @@ return Failure(e) | ||
/** | ||
* Result of the [[Success]] data constructor, representing | ||
* successful values in the [[Try]] disjunction. | ||
* | ||
* @final | ||
*/ | ||
export class TSuccess<A> extends Try<A> { | ||
public readonly value!: A | ||
constructor(value: A) { super(value, "success") } | ||
} | ||
/** | ||
* The `Success` data constructor is for building [[Try]] values that | ||
@@ -1827,6 +1981,17 @@ * are successful results of computations, as opposed to [[Failure]]. | ||
export function Success<A>(value: A): Try<A> { | ||
return new (Try as any)(value, null, true) | ||
return new TSuccess(value) | ||
} | ||
/** | ||
* The `Success` data constructor is for building [[Try]] values that | ||
* are successful results of computations, as opposed to [[Failure]]. | ||
* | ||
* @final | ||
*/ | ||
export class TFailure extends Try<never> { | ||
public readonly value!: Throwable | ||
constructor(value: Throwable) { super(value, "failure") } | ||
} | ||
/** | ||
* The `Failure` data constructor is for building [[Try]] values that | ||
@@ -1836,10 +2001,46 @@ * represent failures, as opposed to [[Success]]. | ||
export function Failure(e: Throwable): Try<never> { | ||
return new (Try as any)(null as never, e, false) | ||
return new TFailure(e) | ||
} | ||
/** | ||
* Type enumerating the type classes implemented by `Try`. | ||
*/ | ||
export type TryTypes = | ||
Setoid<Try<any>> & | ||
Monad<"funfix/try"> | ||
/** | ||
* Type-class implementations, compatible with the `static-land` | ||
* and `funland` specifications. | ||
* | ||
* See [funland-js.org](https://funland-js.org). | ||
*/ | ||
export const TryModule: TryTypes = { | ||
// Setoid | ||
equals: (x, y) => x ? x.equals(y) : !y, | ||
// Functor | ||
map: <A, B>(f: (a: A) => B, fa: Try<A>) => | ||
fa.map(f), | ||
// Apply | ||
ap: <A, B>(ff: Try<(a: A) => B>, fa: Try<A>): Try<B> => | ||
fa.ap(ff), | ||
// Applicative | ||
of: Try.pure, | ||
// Chain | ||
chain: <A, B>(f: (a: A) => Try<B>, fa: Try<A>): Try<B> => | ||
fa.flatMap(f), | ||
// ChainRec | ||
chainRec: <A, B>(f: <C>(next: (a: A) => C, done: (b: B) => C, a: A) => Try<C>, a: A): Try<B> => | ||
Try.tailRecM(a, a => f(Either.left as any, Either.right as any, a)) | ||
} | ||
// Registers Fantasy-Land compatible symbols | ||
fantasyLandRegister(Try, TryModule, TryModule) | ||
/** | ||
* Reusable reference, to use in {@link Try.unit}. | ||
* | ||
* @private | ||
* @hidden | ||
*/ | ||
const tryUnitRef: Try<void> = Success(undefined) |
/*! | ||
* Copyright (c) 2017 by The Funfix Project Developers. | ||
* Copyright (c) 2017-2018 by The Funfix Project Developers. | ||
* Some rights reserved. | ||
@@ -4,0 +4,0 @@ * |
/*! | ||
* Copyright (c) 2017 by The Funfix Project Developers. | ||
* Copyright (c) 2017-2018 by The Funfix Project Developers. | ||
* Some rights reserved. | ||
@@ -19,4 +19,8 @@ * | ||
// Exporting everything | ||
export * from "./kinds" | ||
export * from "./std" | ||
export * from "./errors" | ||
export * from "./disjunctions" | ||
import * as coreInternals from "./internals" | ||
export { coreInternals } |
/*! | ||
* Copyright (c) 2017 by The Funfix Project Developers. | ||
* Copyright (c) 2017-2018 by The Funfix Project Developers. | ||
* Some rights reserved. | ||
@@ -18,2 +18,4 @@ * | ||
import { Setoid } from "funland" | ||
/** | ||
@@ -122,2 +124,8 @@ * Interface for testing the equality of value objects. | ||
/** | ||
* Returns a `Setoid` type-class instance that depends | ||
* universal equality, as defined by {@link is}. | ||
*/ | ||
export const universalSetoid: Setoid<any> = { equals } | ||
/** | ||
* Universal hash-code function. | ||
@@ -124,0 +132,0 @@ * |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 2 instances in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
0
517709
1
46
8576
+ Addedfunland@^0.1.4
+ Addedfunland@0.1.5(transitive)