diff --git a/CHANGELOG.md b/CHANGELOG.md index fc6e37530..7efe269fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,707 @@ **Note**: A feature tagged as Experimental is in a high state of flux, you're at risk of it changing without notice. +# 2.11.0 + +- **Deprecation** + - `Array` + - deprecate `range`, use `NonEmptyArray` module instead. + - `function` + - deprecate `Endomorphism`, use `Endomorphism` module instead. + - deprecate `getEndomorphismMonoid`, use `Endomorphism` module instead. + - deprecate `Predicate`, use `Predicate` module instead. + - deprecate `not`, use `Predicate` module instead. + - deprecate `Refinement`, use `Refinement` module instead. + - `Monoid` + - deprecate `monoidVoid`, use `void` module instead. + - `NonEmptyArray` + - deprecate `groupSort` (it's just `sort` followed by `group`) + - `Option` + - deprecate `getRefinement`, use `Refinement` module instead. + - deprecate `getFirstMonoid`, use `getMonoid` module instead. + - deprecate `getLastMonoid`, use `getMonoid` module instead. + - `ReadonlyArray` + - deprecate `range`, use `ReadonlyNonEmptyArray` module instead. + - `ReadonlyNonEmptyArray` + - deprecate `groupSort` (it's just `sort` followed by `group`) + - `Record` / `ReadonlyRecord`: deprecate overloads without `Ord` constraint (@anthonyjoeseph): + - `collect` + - `reduce` + - `foldMap` + - `reduceRight` + - `reduceWithIndex` + - `foldMapWithIndex` + - `reduceRightWithIndex` + - `getShow` + - deprecate `Foldable` in favour of `getFoldable` (@anthonyjoeseph) + - deprecate `FoldableWithIndex` in favour of `getFoldableWithIndex` (@anthonyjoeseph) + - deprecate `Traversable` in favour of `getTraversable` (@anthonyjoeseph) + - deprecate `TraversableWithIndex` in favour of `getTraversableWithIndex` (@anthonyjoeseph) + - deprecate `Witherable` in favour of `getWitherable` (@anthonyjoeseph) + - `Semigroup` + - deprecate `semigroupVoid`, use `void` module instead. +- **New Feature** + - add `Endomorphism` module + - add `Predicate` module + - add `Refinement` module + - add `FromState` module + - add `FromThese` module + - add `void` module + - add `FromReader` module + - add `NaturalTransformation` module + - add `Zero` module + - `Alt` + - add `altAll` + - `Alternative` + - add `altAll` + - `Array` + - add `prependW`, `appendW` (@thewilkybarkid) + - add `fromOption`, `fromPredicate` (@cdimitroulas) + - add `filterE` + - add `ChainRecDepthFirst` instance (@qlonik) + - add `chainRecDepthFirst` + - add `ChainRecBreadthFirst` instance (@qlonik) + - add `chainRecBreadthFirst` + - add `getUnionSemigroup` + - add `getUnionMonoid` + - add `getIntersectionSemigroup` + - add `getDifferenceMagma` + - add `fromEither` + - add `FromEither` instance + - add `fromEitherK` + - make `isEmpty` a user defined guard + - add `concat` / `concatW` + - add `match`, `matchW`, `matchLeftW`, `matchRightW` + - add `fromOptionK` + - add `Zero` instance + - add `guard` constructor + - add `exists` alias + - `boolean` + - add `isBoolean` + - `Either` + - add `chainOptionK` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `EitherT` + - add `orElseFirst` + - add `orLeft` + - `function` + - add `SK` (@cdimitroulas) + - add `apply` + - `IO` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `IOEither` + - add `orElseFirst` / `orElseFirstW` + - add `orLeft` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - add `traverseReadonlyNonEmptyArrayWithIndexSeq` + - add `traverseReadonlyArrayWithIndexSeq` + - `Magma` + - add `reverse` + - add `filterFirst` + - add `filterSecond` + - add `endo` + - add `concatAll` + - `Map` + - add `union` + - add `intersection` + - add `difference` + - add `getUnionSemigroup` + - add `getUnionMonoid` + - add `getIntersectionSemigroup` + - add `getDifferenceMagma` + - add `getFoldable` + - add `foldMap` + - add `reduceRight` + - add `reduceWithIndex` + - add `foldMapWithIndex` + - add `reduceRightWithIndex` + - `NonEmptyArray` + - add `matchLeft`, `matchRight`, `modifyHead`, `modifyLast` (@cdimitroulas) + - add `union` + - add `getUnionSemigroup` + - add `makeBy` + - add `range` + - make `concat` pipeable + - `number` + - add `MagmaSub` + - add `isNumber` + - `string` + - add `isString` + - `Option` + - add `FromEither` instance + - add `fromEitherK` + - add `chainEitherK` + - add `Zero` instance + - add `guard` constructor + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `Ord` + - add `trivial` instance + - add `equals` + - `Reader` + - add `asksReaderW`, `asksReader` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `ReaderEither` + - add `asksReaderEitherW`, `asksReaderEither` + - add `orElseFirst` / `orElseFirstW` + - add `orLeft` + - add `chainReaderKW` + - add `chainFirstReaderK`, `chainFirstReaderKW` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `ReaderTask` + - add `asksReaderTaskW`, `asksReaderTask` + - add `chainReaderKW` + - add `chainFirstReaderK`, `chainFirstReaderKW` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - add `traverseReadonlyNonEmptyArrayWithIndexSeq` + - add `traverseReadonlyArrayWithIndexSeq` + - `ReaderTaskEither` + - add `asksReaderTaskEitherW`, `asksReaderTaskEither` + - add `orElseFirst` / `orElseFirstW` + - add `orLeft` + - add `fromReaderTaskK` + - add `fromReaderEitherK` + - add `chainReaderKW` + - add `chainReaderTaskK`, `chainReaderTaskKW` + - add `chainFirstReaderK`, `chainFirstReaderKW` + - add `chainFirstReaderTaskK`, `chainFirstReaderTaskKW` + - add `chainReaderEitherK`, `chainReaderEitherKW` + - add `chainFirstReaderEitherK`, `chainFirstReaderEitherKW` + - add `chainFirstTaskEitherK`, `chainFirstTaskEitherKW` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - add `traverseReadonlyNonEmptyArrayWithIndexSeq` + - add `traverseReadonlyArrayWithIndexSeq` + - `ReadonlyArray` + - add `prependW`, `appendW` (@thewilkybarkid) + - add `filterE` + - add `ChainRecDepthFirst` instance (@qlonik) + - add `chainRecDepthFirst` + - add `ChainRecBreadthFirst` instance (@qlonik) + - add `chainRecBreadthFirst` + - add `getUnionSemigroup` + - add `getUnionMonoid` + - add `getIntersectionSemigroup` + - add `getDifferenceMagma` + - add `fromOption` + - add `fromPredicate` + - add `fromEither` + - add `FromEither` instance + - add `fromEitherK` + - make `isEmpty` a user defined guard + - add `concat` / `concatW` + - add `match`, `matchW`, `matchLeftW`, `matchRightW` + - add `fromOptionK` + - add `Zero` instance + - add `guard` constructor + - add `exists` alias + - `ReadonlyMap` + - add `union` + - add `intersection` + - add `difference` + - add `getUnionSemigroup` + - add `getUnionMonoid` + - add `getIntersectionSemigroup` + - add `getDifferenceMagma` + - add `reduce` + - add `foldMap` + - add `reduceRight` + - add `reduceWithIndex` + - add `foldMapWithIndex` + - add `reduceRightWithIndex` + - `ReadonlyNonEmptyArray` + - add `matchLeft`, `matchRight`, `modifyHead`, `modifyLast` (@cdimitroulas) + - add `union` + - add `getUnionSemigroup` + - add `makeBy` + - add `range` + - make `concat` pipeable + - `ReadonlyRecord` + - add `union` (@anthonyjoeseph) + - add `intersection` (@anthonyjoeseph) + - add `difference` (@anthonyjoeseph) + - add `getUnionSemigroup` (@anthonyjoeseph) + - add `getUnionMonoid` (@anthonyjoeseph) + - add `getIntersectionSemigroup` (@anthonyjoeseph) + - add `getDifferenceMagma` (@anthonyjoeseph) + - `ReadonlySet` + - add `getUnionSemigroup` + - add `getDifferenceMagma` + - `Record` + - add `union` + - add `intersection` + - add `difference` + - add `getUnionSemigroup` + - add `getUnionMonoid` + - add `getIntersectionSemigroup` + - add `getDifferenceMagma` + - `Set` + - add `getUnionSemigroup` + - add `getDifferenceMagma` + - `State` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `StateReaderTaskEither` + - add `fromStateK` + - add `chainStateK` + - add `local` + - add `asksStateReaderTaskEitherW`, `asksStateReaderTaskEither` + - add `chainReaderKW` + - add `chainFirstReaderK`, `chainFirstReaderKW` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `string` + - add `toUpperCase` + - add `toLowerCase` + - add `replace` + - add `split` + - add `trim` + - add `trimLeft` + - add `trimRight` + - add `includes` + - add `startsWith` + - add `endsWith` + - add `slice` + - `struct` + - add `evolve` + - `Task` + - add `ApT` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - add `traverseReadonlyNonEmptyArrayWithIndexSeq` + - add `traverseReadonlyArrayWithIndexSeq` + - `TaskEither` + - add `fromTaskOption` (@thewilkybarkid) + - add `fromTaskOptionK` + - add `chainTaskOptionK` + - add `orElseFirst` / `orElseFirstW` + - add `orLeft` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - add `traverseReadonlyNonEmptyArrayWithIndexSeq` + - add `traverseReadonlyArrayWithIndexSeq` + - `TaskOption` + - add `fromTaskEither` (@thewilkybarkid) + - add `Zero` instance + - add `guard` constructor + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - add `traverseReadonlyNonEmptyArrayWithIndexSeq` + - add `traverseReadonlyArrayWithIndexSeq` + - add missing `FromEither` instance + - `TaskThese` + - add `ApT` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - add `traverseReadonlyNonEmptyArrayWithIndexSeq` + - add `traverseReadonlyArrayWithIndexSeq` + - `These` + - add `elem` + - add `exists` + - add `ApT` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `Tree` + - add `exists` + - `Witherable` + - add `filterE`, #1458 (@vinassefranche) + - add `wiltDefault` + - add `witherDefault` +- **Polish** + - remove unnecessary type parameters + - `Either` + - `isLeft` + - `isRight` + - `Option` + - `isNone` + - `These` + - `isLeft` + - `isRight` + +# 2.11.0-rc.2 + +- `string` + - `split` now returns a `ReadonlyNonEmptyArray` +- `TaskOption` + - add missing `FromEither` instance +- some signature changes in `2.11.0-rc.1` caused type inference issues + - `Array` / `ReadonlyArray` + - revert `isOutOfBound` signature change + - revert `isEmpty` signature change + - revert `size` signature change + - `Either` + - revert `exists` signature change + - revert `elem` signature change + - `These` + - revert `exists` signature change + - revert `elem` signature change + - `NonEmptyArray` / `ReadonlyNonEmptyArray` + - revert `isOutOfBound` signature change + - `Set` / `ReadonlySet` + - revert `isEmpty` signature change + - revert `size` signature change + - `Map` / `ReadonlyMap` + - revert `isEmpty` signature change + - revert `size` signature change + +# 2.11.0-rc.1 + +- **Deprecation** + - `Array` + - deprecate `range`, use `NonEmptyArray` module instead. + - `function` + - deprecate `Endomorphism`, use `Endomorphism` module instead. + - deprecate `getEndomorphismMonoid`, use `Endomorphism` module instead. + - deprecate `Predicate`, use `Predicate` module instead. + - deprecate `not`, use `Predicate` module instead. + - deprecate `Refinement`, use `Refinement` module instead. + - `Monoid` + - deprecate `monoidVoid`, use `void` module instead. + - `NonEmptyArray` + - deprecate `groupSort` (it's just `sort` followed by `group`) + - `Option` + - deprecate `getRefinement`, use `Refinement` module instead. + - deprecate `getFirstMonoid`, use `getMonoid` module instead. + - deprecate `getLastMonoid`, use `getMonoid` module instead. + - `ReadonlyArray` + - deprecate `range`, use `ReadonlyNonEmptyArray` module instead. + - `ReadonlyNonEmptyArray` + - deprecate `groupSort` (it's just `sort` followed by `group`) + - `Record` / `ReadonlyRecord`: deprecate overloads without `Ord` constraint (@anthonyjoeseph): + - `collect` + - `reduce` + - `foldMap` + - `reduceRight` + - `reduceWithIndex` + - `foldMapWithIndex` + - `reduceRightWithIndex` + - `getShow` + - deprecate `Foldable` in favour of `getFoldable` (@anthonyjoeseph) + - deprecate `FoldableWithIndex` in favour of `getFoldableWithIndex` (@anthonyjoeseph) + - deprecate `Traversable` in favour of `getTraversable` (@anthonyjoeseph) + - deprecate `TraversableWithIndex` in favour of `getTraversableWithIndex` (@anthonyjoeseph) + - deprecate `Witherable` in favour of `getWitherable` (@anthonyjoeseph) + - `Semigroup` + - deprecate `semigroupVoid`, use `void` module instead. +- **New Feature** + - add `Endomorphism` module + - add `Predicate` module + - add `Refinement` module + - add `FromState` module + - add `FromThese` module + - add `void` module + - add `FromReader` module + - add `NaturalTransformation` module + - add `Zero` module + - `Alt` + - add `altAll` + - `Alternative` + - add `altAll` + - `Array` + - add `prependW`, `appendW` (@thewilkybarkid) + - add `fromOption`, `fromPredicate` (@cdimitroulas) + - add `filterE` + - add `ChainRecDepthFirst` instance (@qlonik) + - add `chainRecDepthFirst` + - add `ChainRecBreadthFirst` instance (@qlonik) + - add `chainRecBreadthFirst` + - add `getUnionSemigroup` + - add `getUnionMonoid` + - add `getIntersectionSemigroup` + - add `getDifferenceMagma` + - add `fromEither` + - add `FromEither` instance + - add `fromEitherK` + - make `isEmpty` a user defined guard + - add `concat` / `concatW` + - add `match`, `matchW`, `matchLeftW`, `matchRightW` + - add `fromOptionK` + - add `Zero` instance + - add `guard` constructor + - add `exists` alias + - `boolean` + - add `isBoolean` + - `Either` + - add `chainOptionK` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `EitherT` + - add `orElseFirst` + - add `orLeft` + - `function` + - add `SK` (@cdimitroulas) + - add `apply` + - `IO` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `IOEither` + - add `orElseFirst` / `orElseFirstW` + - add `orLeft` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - add `traverseReadonlyNonEmptyArrayWithIndexSeq` + - add `traverseReadonlyArrayWithIndexSeq` + - `Magma` + - add `reverse` + - add `filterFirst` + - add `filterSecond` + - add `endo` + - add `concatAll` + - `Map` + - add `union` + - add `intersection` + - add `difference` + - add `getUnionSemigroup` + - add `getUnionMonoid` + - add `getIntersectionSemigroup` + - add `getDifferenceMagma` + - add `getFoldable` + - add `foldMap` + - add `reduceRight` + - add `reduceWithIndex` + - add `foldMapWithIndex` + - add `reduceRightWithIndex` + - `NonEmptyArray` + - add `matchLeft`, `matchRight`, `modifyHead`, `modifyLast` (@cdimitroulas) + - add `union` + - add `getUnionSemigroup` + - add `makeBy` + - add `range` + - make `concat` pipeable + - `number` + - add `MagmaSub` + - add `isNumber` + - `string` + - add `isString` + - `Option` + - add `FromEither` instance + - add `fromEitherK` + - add `chainEitherK` + - add `Zero` instance + - add `guard` constructor + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `Ord` + - add `trivial` instance + - add `equals` + - `Reader` + - add `asksReaderW`, `asksReader` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `ReaderEither` + - add `asksReaderEitherW`, `asksReaderEither` + - add `orElseFirst` / `orElseFirstW` + - add `orLeft` + - add `chainReaderKW` + - add `chainFirstReaderK`, `chainFirstReaderKW` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `ReaderTask` + - add `asksReaderTaskW`, `asksReaderTask` + - add `chainReaderKW` + - add `chainFirstReaderK`, `chainFirstReaderKW` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - add `traverseReadonlyNonEmptyArrayWithIndexSeq` + - add `traverseReadonlyArrayWithIndexSeq` + - `ReaderTaskEither` + - add `asksReaderTaskEitherW`, `asksReaderTaskEither` + - add `orElseFirst` / `orElseFirstW` + - add `orLeft` + - add `fromReaderTaskK` + - add `fromReaderEitherK` + - add `chainReaderKW` + - add `chainReaderTaskK`, `chainReaderTaskKW` + - add `chainFirstReaderK`, `chainFirstReaderKW` + - add `chainFirstReaderTaskK`, `chainFirstReaderTaskKW` + - add `chainReaderEitherK`, `chainReaderEitherKW` + - add `chainFirstReaderEitherK`, `chainFirstReaderEitherKW` + - add `chainFirstTaskEitherK`, `chainFirstTaskEitherKW` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - add `traverseReadonlyNonEmptyArrayWithIndexSeq` + - add `traverseReadonlyArrayWithIndexSeq` + - `ReadonlyArray` + - add `prependW`, `appendW` (@thewilkybarkid) + - add `filterE` + - add `ChainRecDepthFirst` instance (@qlonik) + - add `chainRecDepthFirst` + - add `ChainRecBreadthFirst` instance (@qlonik) + - add `chainRecBreadthFirst` + - add `getUnionSemigroup` + - add `getUnionMonoid` + - add `getIntersectionSemigroup` + - add `getDifferenceMagma` + - add `fromOption` + - add `fromPredicate` + - add `fromEither` + - add `FromEither` instance + - add `fromEitherK` + - make `isEmpty` a user defined guard + - add `concat` / `concatW` + - add `match`, `matchW`, `matchLeftW`, `matchRightW` + - add `fromOptionK` + - add `Zero` instance + - add `guard` constructor + - add `exists` alias + - `ReadonlyMap` + - add `union` + - add `intersection` + - add `difference` + - add `getUnionSemigroup` + - add `getUnionMonoid` + - add `getIntersectionSemigroup` + - add `getDifferenceMagma` + - add `reduce` + - add `foldMap` + - add `reduceRight` + - add `reduceWithIndex` + - add `foldMapWithIndex` + - add `reduceRightWithIndex` + - `ReadonlyNonEmptyArray` + - add `matchLeft`, `matchRight`, `modifyHead`, `modifyLast` (@cdimitroulas) + - add `union` + - add `getUnionSemigroup` + - add `makeBy` + - add `range` + - make `concat` pipeable + - `ReadonlyRecord` + - add `union` (@anthonyjoeseph) + - add `intersection` (@anthonyjoeseph) + - add `difference` (@anthonyjoeseph) + - add `getUnionSemigroup` (@anthonyjoeseph) + - add `getUnionMonoid` (@anthonyjoeseph) + - add `getIntersectionSemigroup` (@anthonyjoeseph) + - add `getDifferenceMagma` (@anthonyjoeseph) + - `ReadonlySet` + - add `getUnionSemigroup` + - add `getDifferenceMagma` + - `Record` + - add `union` + - add `intersection` + - add `difference` + - add `getUnionSemigroup` + - add `getUnionMonoid` + - add `getIntersectionSemigroup` + - add `getDifferenceMagma` + - `Set` + - add `getUnionSemigroup` + - add `getDifferenceMagma` + - `State` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `StateReaderTaskEither` + - add `fromStateK` + - add `chainStateK` + - add `local` + - add `asksStateReaderTaskEitherW`, `asksStateReaderTaskEither` + - add `chainReaderKW` + - add `chainFirstReaderK`, `chainFirstReaderKW` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `string` + - add `toUpperCase` + - add `toLowerCase` + - add `replace` + - add `split` + - add `trim` + - add `trimLeft` + - add `trimRight` + - add `includes` + - add `startsWith` + - add `endsWith` + - add `slice` + - `struct` + - add `evolve` + - `Task` + - add `ApT` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - add `traverseReadonlyNonEmptyArrayWithIndexSeq` + - add `traverseReadonlyArrayWithIndexSeq` + - `TaskEither` + - add `fromTaskOption` (@thewilkybarkid) + - add `fromTaskOptionK` + - add `chainTaskOptionK` + - add `orElseFirst` / `orElseFirstW` + - add `orLeft` + - add `flattenW` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - add `traverseReadonlyNonEmptyArrayWithIndexSeq` + - add `traverseReadonlyArrayWithIndexSeq` + - `TaskOption` + - add `fromTaskEither` (@thewilkybarkid) + - add `Zero` instance + - add `guard` constructor + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - add `traverseReadonlyNonEmptyArrayWithIndexSeq` + - add `traverseReadonlyArrayWithIndexSeq` + - `TaskThese` + - add `ApT` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - add `traverseReadonlyNonEmptyArrayWithIndexSeq` + - add `traverseReadonlyArrayWithIndexSeq` + - `These` + - add `elem` + - add `exists` + - add `ApT` + - add `traverseReadonlyNonEmptyArrayWithIndex` + - add `traverseReadonlyArrayWithIndex` + - `Tree` + - add `exists` + - `Witherable` + - add `filterE`, #1458 (@vinassefranche) + - add `wiltDefault` + - add `witherDefault` +- **Polish** + - remove unnecessary type parameters + - `Either` + - `exists` + - `isLeft` + - `isRight` + - `elem` + - `Option` + - `isNone` + - `These` + - `isLeft` + - `isRight` + - `Set` / `ReadonlySet` + - `isEmpty` + - `size` + - `Array` / `ReadonlyArray` + - `isEmpty` + - `isOutOfBound` + - `size` + - `Map` / `ReadonlyMap` + - `isEmpty` + - `size` + - `NonEmptyArray` / `ReadonlyNonEmptyArray` + - `isOutOfBound` + # 2.10.5 - **Bug Fix** @@ -103,7 +804,7 @@ high state of flux, you're at risk of it changing without notice. - deprecate `fromIO` - `IOEither` - deprecate `getApplySemigroup` in favour of `Apply.getApplySemigroup` - - deprecate `getApplyMonoid` in favour of `Applicative.getApplicativeMonoid` + - daprecate `getApplyMonoid` in favour of `Applicative.getApplicativeMonoid` - deprecate `getSemigroup` in favour of `Apply.getApplySemigroup` - deprecate `getIOValidation`, use `getApplicativeIOValidation` and `getAltIOValidation` instead - `Map` diff --git a/docs/modules/Alt.ts.md b/docs/modules/Alt.ts.md index 4a5fcc4bb..81f0b784e 100644 --- a/docs/modules/Alt.ts.md +++ b/docs/modules/Alt.ts.md @@ -29,6 +29,8 @@ Added in v2.0.0 - [Alt3 (interface)](#alt3-interface) - [Alt3C (interface)](#alt3c-interface) - [Alt4 (interface)](#alt4-interface) +- [utils](#utils) + - [altAll](#altall) --- @@ -117,3 +119,33 @@ export interface Alt4 extends Functor4 { ``` Added in v2.0.0 + +# utils + +## altAll + +**Signature** + +```ts +export declare function altAll( + F: Alt4 +): (startWith: Kind4) => (as: ReadonlyArray>) => Kind4 +export declare function altAll( + F: Alt3 +): (startWith: Kind3) => (as: ReadonlyArray>) => Kind3 +export declare function altAll( + F: Alt3C +): (startWith: Kind3) => (as: ReadonlyArray>) => Kind3 +export declare function altAll( + F: Alt2 +): (startWith: Kind2) => (as: ReadonlyArray>) => Kind2 +export declare function altAll( + F: Alt2C +): (startWith: Kind2) => (as: ReadonlyArray>) => Kind2 +export declare function altAll( + F: Alt1 +): (startWith: Kind) => (as: ReadonlyArray>) => Kind +export declare function altAll(F: Alt): (startWith: HKT) => (as: ReadonlyArray>) => HKT +``` + +Added in v2.11.0 diff --git a/docs/modules/Alternative.ts.md b/docs/modules/Alternative.ts.md index 5f24bb2a5..1efd9c7fb 100644 --- a/docs/modules/Alternative.ts.md +++ b/docs/modules/Alternative.ts.md @@ -33,6 +33,8 @@ Added in v2.0.0 - [Alternative3 (interface)](#alternative3-interface) - [Alternative3C (interface)](#alternative3c-interface) - [Alternative4 (interface)](#alternative4-interface) +- [utils](#utils) + - [altAll](#altall) --- @@ -43,9 +45,7 @@ Added in v2.0.0 **Signature** ```ts -export interface Alternative extends Applicative, Alt { - readonly zero: () => HKT -} +export interface Alternative extends Applicative, Alt, Zero {} ``` Added in v2.0.0 @@ -55,9 +55,7 @@ Added in v2.0.0 **Signature** ```ts -export interface Alternative1 extends Applicative1, Alt1 { - readonly zero: () => Kind -} +export interface Alternative1 extends Applicative1, Alt1, Zero1 {} ``` Added in v2.0.0 @@ -67,9 +65,7 @@ Added in v2.0.0 **Signature** ```ts -export interface Alternative2 extends Applicative2, Alt2 { - readonly zero: () => Kind2 -} +export interface Alternative2 extends Applicative2, Alt2, Zero2 {} ``` Added in v2.0.0 @@ -79,9 +75,7 @@ Added in v2.0.0 **Signature** ```ts -export interface Alternative2C extends Applicative2C, Alt2C { - readonly zero: () => Kind2 -} +export interface Alternative2C extends Applicative2C, Alt2C, Zero2C {} ``` Added in v2.0.0 @@ -91,9 +85,7 @@ Added in v2.0.0 **Signature** ```ts -export interface Alternative3 extends Applicative3, Alt3 { - readonly zero: () => Kind3 -} +export interface Alternative3 extends Applicative3, Alt3, Zero3 {} ``` Added in v2.0.0 @@ -103,9 +95,7 @@ Added in v2.0.0 **Signature** ```ts -export interface Alternative3C extends Applicative3C, Alt3C { - readonly zero: () => Kind3 -} +export interface Alternative3C extends Applicative3C, Alt3C, Zero3C {} ``` Added in v2.10.0 @@ -115,9 +105,35 @@ Added in v2.10.0 **Signature** ```ts -export interface Alternative4 extends Applicative4, Alt4 { - readonly zero: () => Kind4 -} +export interface Alternative4 extends Applicative4, Alt4, Zero4 {} ``` Added in v2.10.0 + +# utils + +## altAll + +**Signature** + +```ts +export declare function altAll( + F: Alternative4 +): (as: ReadonlyArray>) => Kind4 +export declare function altAll( + F: Alternative3 +): (as: ReadonlyArray>) => Kind3 +export declare function altAll( + F: Alternative3C +): (as: ReadonlyArray>) => Kind3 +export declare function altAll( + F: Alternative2 +): (as: ReadonlyArray>) => Kind2 +export declare function altAll( + F: Alternative2C +): (as: ReadonlyArray>) => Kind2 +export declare function altAll(F: Alternative1): (as: ReadonlyArray>) => Kind +export declare function altAll(F: Alternative): (as: ReadonlyArray>) => HKT +``` + +Added in v2.11.0 diff --git a/docs/modules/Array.ts.md b/docs/modules/Array.ts.md index fd723f6b4..003085f7a 100644 --- a/docs/modules/Array.ts.md +++ b/docs/modules/Array.ts.md @@ -15,10 +15,11 @@ Added in v2.0.0 - [Alt](#alt) - [alt](#alt) - [altW](#altw) -- [Alternative](#alternative) - - [zero](#zero) - [Apply](#apply) - [ap](#ap) +- [ChainRec](#chainrec) + - [chainRecBreadthFirst](#chainrecbreadthfirst) + - [chainRecDepthFirst](#chainrecdepthfirst) - [Compactable](#compactable) - [compact](#compact) - [separate](#separate) @@ -60,6 +61,8 @@ Added in v2.0.0 - [Witherable](#witherable) - [wilt](#wilt) - [wither](#wither) +- [Zero](#zero) + - [zero](#zero) - [combinators](#combinators) - [apFirst](#apfirst) - [apSecond](#apsecond) @@ -68,6 +71,8 @@ Added in v2.0.0 - [chop](#chop) - [chunksOf](#chunksof) - [comprehension](#comprehension) + - [concat](#concat) + - [concatW](#concatw) - [copy](#copy) - [difference](#difference) - [dropLeft](#dropleft) @@ -76,6 +81,8 @@ Added in v2.0.0 - [duplicate](#duplicate) - [flap](#flap) - [flatten](#flatten) + - [fromEitherK](#fromeitherk) + - [fromOptionK](#fromoptionk) - [intersection](#intersection) - [intersperse](#intersperse) - [lefts](#lefts) @@ -98,11 +105,15 @@ Added in v2.0.0 - [~~prependToAll~~](#prependtoall) - [constructors](#constructors) - [append](#append) + - [appendW](#appendw) + - [fromPredicate](#frompredicate) + - [guard](#guard) - [makeBy](#makeby) - [prepend](#prepend) - - [range](#range) + - [prependW](#prependw) - [replicate](#replicate) - [~~cons~~](#cons) + - [~~range~~](#range) - [~~snoc~~](#snoc) - [destructors](#destructors) - [findFirst](#findfirst) @@ -114,24 +125,29 @@ Added in v2.0.0 - [head](#head) - [init](#init) - [last](#last) + - [match](#match) - [matchLeft](#matchleft) + - [matchLeftW](#matchleftw) - [matchRight](#matchright) + - [matchRightW](#matchrightw) + - [matchW](#matchw) - [spanLeft](#spanleft) - [tail](#tail) -- [guards](#guards) - - [isNonEmpty](#isnonempty) - [instances](#instances) - [Alt](#alt-1) - - [Alternative](#alternative-1) + - [Alternative](#alternative) - [Applicative](#applicative) - [Apply](#apply-1) - [Chain](#chain) + - [ChainRecBreadthFirst](#chainrecbreadthfirst) + - [ChainRecDepthFirst](#chainrecdepthfirst) - [Compactable](#compactable-1) - [Extend](#extend-1) - [Filterable](#filterable-1) - [FilterableWithIndex](#filterablewithindex-1) - [Foldable](#foldable-1) - [FoldableWithIndex](#foldablewithindex-1) + - [FromEither](#fromeither) - [Functor](#functor-1) - [FunctorWithIndex](#functorwithindex-1) - [Monad](#monad-1) @@ -142,12 +158,23 @@ Added in v2.0.0 - [URI (type alias)](#uri-type-alias) - [Unfoldable](#unfoldable-1) - [Witherable](#witherable-1) + - [Zero](#zero-1) + - [getDifferenceMagma](#getdifferencemagma) - [getEq](#geteq) + - [getIntersectionSemigroup](#getintersectionsemigroup) - [getMonoid](#getmonoid) - [getOrd](#getord) - [getSemigroup](#getsemigroup) - [getShow](#getshow) + - [getUnionMonoid](#getunionmonoid) + - [getUnionSemigroup](#getunionsemigroup) - [~~array~~](#array) +- [natural transformations](#natural-transformations) + - [fromEither](#fromeither) + - [fromOption](#fromoption) +- [refinements](#refinements) + - [isEmpty](#isempty) + - [isNonEmpty](#isnonempty) - [unsafe](#unsafe) - [unsafeDeleteAt](#unsafedeleteat) - [unsafeInsertAt](#unsafeinsertat) @@ -161,10 +188,11 @@ Added in v2.0.0 - [deleteAt](#deleteat) - [elem](#elem) - [every](#every) + - [exists](#exists) + - [filterE](#filtere) - [findIndex](#findindex) - [findLastIndex](#findlastindex) - [insertAt](#insertat) - - [isEmpty](#isempty) - [isOutOfBound](#isoutofbound) - [lookup](#lookup) - [modifyAt](#modifyat) @@ -203,31 +231,41 @@ export declare const altW: (that: Lazy) => (fa: A[]) => (B | A)[] Added in v2.9.0 -# Alternative +# Apply -## zero +## ap + +Apply a function to an argument under a type constructor. **Signature** ```ts -export declare const zero: () => A[] +export declare const ap: (fa: A[]) => (fab: ((a: A) => B)[]) => B[] ``` -Added in v2.7.0 +Added in v2.0.0 -# Apply +# ChainRec -## ap +## chainRecBreadthFirst -Apply a function to an argument under a type constructor. +**Signature** + +```ts +export declare const chainRecBreadthFirst: (f: (a: A) => Either[]) => (a: A) => B[] +``` + +Added in v2.11.0 + +## chainRecDepthFirst **Signature** ```ts -export declare const ap: (fa: A[]) => (fab: ((a: A) => B)[]) => B[] +export declare const chainRecDepthFirst: (f: (a: A) => Either[]) => (a: A) => B[] ``` -Added in v2.0.0 +Added in v2.11.0 # Compactable @@ -236,7 +274,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const compact: (fa: O.Option[]) => A[] +export declare const compact: (fa: Option[]) => A[] ``` Added in v2.0.0 @@ -258,7 +296,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const extend: (f: (fa: A[]) => B) => (wa: A[]) => B[] +export declare const extend: (f: (as: A[]) => B) => (as: A[]) => B[] ``` Added in v2.0.0 @@ -271,8 +309,9 @@ Added in v2.0.0 ```ts export declare const filter: { - (refinement: Refinement): (fa: A[]) => B[] - (predicate: Predicate): (fa: A[]) => A[] + (refinement: Refinement): (as: A[]) => B[] + (predicate: Predicate): (bs: B[]) => B[] + (predicate: Predicate): (as: A[]) => A[] } ``` @@ -283,7 +322,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const filterMap: (f: (a: A) => O.Option) => (fa: A[]) => B[] +export declare const filterMap: (f: (a: A) => Option) => (fa: A[]) => B[] ``` Added in v2.0.0 @@ -294,8 +333,9 @@ Added in v2.0.0 ```ts export declare const partition: { - (refinement: Refinement): (fa: A[]) => Separated - (predicate: Predicate): (fa: A[]) => Separated + (refinement: Refinement): (as: A[]) => Separated + (predicate: Predicate): (bs: B[]) => Separated + (predicate: Predicate): (as: A[]) => Separated } ``` @@ -318,7 +358,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const filterMapWithIndex: (f: (i: number, a: A) => O.Option) => (fa: A[]) => B[] +export declare const filterMapWithIndex: (f: (i: number, a: A) => Option) => (fa: A[]) => B[] ``` Added in v2.0.0 @@ -329,8 +369,9 @@ Added in v2.0.0 ```ts export declare const filterWithIndex: { - (refinementWithIndex: RefinementWithIndex): (fa: A[]) => B[] - (predicateWithIndex: PredicateWithIndex): (fa: A[]) => A[] + (refinementWithIndex: RefinementWithIndex): (as: A[]) => B[] + (predicateWithIndex: PredicateWithIndex): (bs: B[]) => B[] + (predicateWithIndex: PredicateWithIndex): (as: A[]) => A[] } ``` @@ -354,8 +395,9 @@ Added in v2.0.0 ```ts export declare const partitionWithIndex: { - (refinementWithIndex: RefinementWithIndex): (fa: A[]) => Separated - (predicateWithIndex: PredicateWithIndex): (fa: A[]) => Separated + (refinementWithIndex: RefinementWithIndex): (as: A[]) => Separated + (predicateWithIndex: PredicateWithIndex): (bs: B[]) => Separated + (predicateWithIndex: PredicateWithIndex): (as: A[]) => Separated } ``` @@ -516,10 +558,25 @@ Added in v2.6.3 ## unfold +Creates an `Array` from the results of `f(b)`, where `b` is an initial value. +`unfold` stops when `f` returns `Option.none`. + **Signature** ```ts -export declare const unfold: (b: B, f: (b: B) => O.Option) => A[] +export declare const unfold: (b: B, f: (b: B) => Option) => A[] +``` + +**Example** + +```ts +import { unfold } from 'fp-ts/Array' +import { some, none } from 'fp-ts/Option' + +assert.deepStrictEqual( + unfold(5, (n) => (n > 0 ? some([n, n - 1]) : none)), + [5, 4, 3, 2, 1] +) ``` Added in v2.6.6 @@ -546,6 +603,18 @@ export declare const wither: PipeableWither1<'Array'> Added in v2.6.5 +# Zero + +## zero + +**Signature** + +```ts +export declare const zero: () => A[] +``` + +Added in v2.7.0 + # combinators ## apFirst @@ -718,6 +787,26 @@ assert.deepStrictEqual( Added in v2.0.0 +## concat + +**Signature** + +```ts +export declare const concat: (second: A[]) => (first: A[]) => A[] +``` + +Added in v2.11.0 + +## concatW + +**Signature** + +```ts +export declare const concatW: (second: B[]) => (first: A[]) => (B | A)[] +``` + +Added in v2.11.0 + ## copy **Signature** @@ -785,7 +874,9 @@ Remove the longest initial subarray for which all element satisfy the specified **Signature** ```ts -export declare const dropLeftWhile: (predicate: Predicate) => (as: A[]) => A[] +export declare function dropLeftWhile(refinement: Refinement): (as: Array) => Array +export declare function dropLeftWhile(predicate: Predicate): (bs: Array) => Array +export declare function dropLeftWhile(predicate: Predicate): (as: Array) => Array ``` **Example** @@ -856,6 +947,26 @@ export declare const flatten: (mma: A[][]) => A[] Added in v2.5.0 +## fromEitherK + +**Signature** + +```ts +export declare const fromEitherK: (f: (...a: A) => Either) => (...a: A) => B[] +``` + +Added in v2.11.0 + +## fromOptionK + +**Signature** + +```ts +export declare const fromOptionK: (f: (...a: A) => Option) => (...a: A) => B[] +``` + +Added in v2.11.0 + ## intersection Creates an array of unique values that are included in all given arrays using a `Eq` for equality @@ -1171,6 +1282,7 @@ Calculate the longest initial subarray for which all element satisfy the specifi ```ts export declare function takeLeftWhile(refinement: Refinement): (as: Array) => Array +export declare function takeLeftWhile(predicate: Predicate): (bs: Array) => Array export declare function takeLeftWhile(predicate: Predicate): (as: Array) => Array ``` @@ -1340,6 +1452,40 @@ assert.deepStrictEqual(pipe([1, 2, 3], append(4)), [1, 2, 3, 4]) Added in v2.10.0 +## appendW + +Less strict version of [`append`](#append). + +**Signature** + +```ts +export declare const appendW: (end: B) => (init: A[]) => NEA.NonEmptyArray +``` + +Added in v2.11.0 + +## fromPredicate + +**Signature** + +```ts +export declare function fromPredicate(refinement: Refinement): (a: A) => Array +export declare function fromPredicate(predicate: Predicate): (b: B) => Array +export declare function fromPredicate(predicate: Predicate): (a: A) => Array +``` + +Added in v2.11.0 + +## guard + +**Signature** + +```ts +export declare const guard: (b: boolean) => void[] +``` + +Added in v2.11.0 + ## makeBy Return a `Array` of length `n` with element `i` initialized with `f(i)`. @@ -1384,25 +1530,17 @@ assert.deepStrictEqual(pipe([2, 3, 4], prepend(1)), [1, 2, 3, 4]) Added in v2.10.0 -## range +## prependW -Create an `Array` containing a range of integers, including both endpoints. +Less strict version of [`prepend`](#prepend). **Signature** ```ts -export declare const range: (start: number, end: number) => Array -``` - -**Example** - -```ts -import { range } from 'fp-ts/Array' - -assert.deepStrictEqual(range(1, 5), [1, 2, 3, 4, 5]) +export declare const prependW: (head: B) => (tail: A[]) => NEA.NonEmptyArray ``` -Added in v2.0.0 +Added in v2.11.0 ## replicate @@ -1438,6 +1576,18 @@ export declare const cons: typeof NEA.cons Added in v2.0.0 +## ~~range~~ + +Use `NonEmptyArray` module instead. + +**Signature** + +```ts +export declare const range: (start: number, end: number) => NEA.NonEmptyArray +``` + +Added in v2.0.0 + ## ~~snoc~~ Use `append` instead. @@ -1460,6 +1610,7 @@ Find the first element which satisfies a predicate (or a refinement) function ```ts export declare function findFirst(refinement: Refinement): (as: Array) => Option +export declare function findFirst(predicate: Predicate): (bs: Array) => Option export declare function findFirst(predicate: Predicate): (as: Array) => Option ``` @@ -1492,7 +1643,7 @@ Find the first element returned by an option based selector function **Signature** ```ts -export declare const findFirstMap: (f: (a: A) => O.Option) => (as: A[]) => O.Option +export declare const findFirstMap: (f: (a: A) => Option) => (as: A[]) => Option ``` **Example** @@ -1522,6 +1673,7 @@ Find the last element which satisfies a predicate function ```ts export declare function findLast(refinement: Refinement): (as: Array) => Option +export declare function findLast(predicate: Predicate): (bs: Array) => Option export declare function findLast(predicate: Predicate): (as: Array) => Option ``` @@ -1554,7 +1706,7 @@ Find the last element returned by an option based selector function **Signature** ```ts -export declare const findLastMap: (f: (a: A) => O.Option) => (as: A[]) => O.Option +export declare const findLastMap: (f: (a: A) => Option) => (as: A[]) => Option ``` **Example** @@ -1607,7 +1759,7 @@ Get the first element in an array, or `None` if the array is empty **Signature** ```ts -export declare const head: (as: A[]) => O.Option +export declare const head: (as: A[]) => Option ``` **Example** @@ -1629,7 +1781,7 @@ Get all but the last element of an array, creating a new array, or `None` if the **Signature** ```ts -export declare const init: (as: A[]) => O.Option +export declare const init: (as: A[]) => Option ``` **Example** @@ -1651,7 +1803,7 @@ Get the last element in an array, or `None` if the array is empty **Signature** ```ts -export declare const last: (as: A[]) => O.Option +export declare const last: (as: A[]) => Option ``` **Example** @@ -1666,9 +1818,21 @@ assert.deepStrictEqual(last([]), none) Added in v2.0.0 +## match + +Less strict version of [`match`](#match). + +**Signature** + +```ts +export declare const match: (onEmpty: Lazy, onNonEmpty: (as: NEA.NonEmptyArray) => B) => (as: A[]) => B +``` + +Added in v2.11.0 + ## matchLeft -Break an array into its first element and remaining elements +Break an `Array` into its first element and remaining elements. **Signature** @@ -1690,9 +1854,24 @@ assert.strictEqual(len([1, 2, 3]), 3) Added in v2.10.0 +## matchLeftW + +Less strict version of [`matchLeft`](#matchleft). + +**Signature** + +```ts +export declare const matchLeftW: ( + onEmpty: Lazy, + onNonEmpty: (head: A, tail: A[]) => C +) => (as: A[]) => B | C +``` + +Added in v2.11.0 + ## matchRight -Break an array into its initial elements and the last element +Break an `Array` into its initial elements and the last element. **Signature** @@ -1702,6 +1881,36 @@ export declare const matchRight: (onEmpty: Lazy, onNonEmpty: (init: A[] Added in v2.10.0 +## matchRightW + +Less strict version of [`matchRight`](#matchright). + +**Signature** + +```ts +export declare const matchRightW: ( + onEmpty: Lazy, + onNonEmpty: (init: A[], last: A) => C +) => (as: A[]) => B | C +``` + +Added in v2.11.0 + +## matchW + +Less strict version of [`match`](#match). + +**Signature** + +```ts +export declare const matchW: ( + onEmpty: Lazy, + onNonEmpty: (as: NEA.NonEmptyArray) => C +) => (as: A[]) => B | C +``` + +Added in v2.11.0 + ## spanLeft Split an array into two parts: @@ -1713,6 +1922,7 @@ Split an array into two parts: ```ts export declare function spanLeft(refinement: Refinement): (as: Array) => Spanned +export declare function spanLeft(predicate: Predicate): (bs: Array) => Spanned export declare function spanLeft(predicate: Predicate): (as: Array) => Spanned ``` @@ -1733,7 +1943,7 @@ Get all but the first element of an array, creating a new array, or `None` if th **Signature** ```ts -export declare const tail: (as: A[]) => O.Option +export declare const tail: (as: A[]) => Option ``` **Example** @@ -1748,20 +1958,6 @@ assert.deepStrictEqual(tail([]), none) Added in v2.0.0 -# guards - -## isNonEmpty - -Test whether an array is non empty narrowing down the type to `NonEmptyArray` - -**Signature** - -```ts -export declare const isNonEmpty: (as: A[]) => as is NEA.NonEmptyArray -``` - -Added in v2.0.0 - # instances ## Alt @@ -1814,6 +2010,26 @@ export declare const Chain: Chain1<'Array'> Added in v2.10.0 +## ChainRecBreadthFirst + +**Signature** + +```ts +export declare const ChainRecBreadthFirst: ChainRec1<'Array'> +``` + +Added in v2.11.0 + +## ChainRecDepthFirst + +**Signature** + +```ts +export declare const ChainRecDepthFirst: ChainRec1<'Array'> +``` + +Added in v2.11.0 + ## Compactable **Signature** @@ -1874,6 +2090,16 @@ export declare const FoldableWithIndex: FoldableWithIndex1<'Array', number> Added in v2.7.0 +## FromEither + +**Signature** + +```ts +export declare const FromEither: FromEither1<'Array'> +``` + +Added in v2.11.0 + ## Functor **Signature** @@ -1974,6 +2200,26 @@ export declare const Witherable: Witherable1<'Array'> Added in v2.7.0 +## Zero + +**Signature** + +```ts +export declare const Zero: Zero1<'Array'> +``` + +Added in v2.11.0 + +## getDifferenceMagma + +**Signature** + +```ts +export declare const getDifferenceMagma: (E: Eq) => Magma +``` + +Added in v2.11.0 + ## getEq Derives an `Eq` over the `Array` of a given element type from the `Eq` of that type. The derived `Eq` defines two @@ -1999,6 +2245,16 @@ assert.strictEqual(E.equals(['a'], []), false) Added in v2.0.0 +## getIntersectionSemigroup + +**Signature** + +```ts +export declare const getIntersectionSemigroup: (E: Eq) => Semigroup +``` + +Added in v2.11.0 + ## getMonoid Returns a `Monoid` for `Array` @@ -2067,6 +2323,26 @@ export declare const getShow: (S: Show) => Show Added in v2.0.0 +## getUnionMonoid + +**Signature** + +```ts +export declare const getUnionMonoid: (E: Eq) => Monoid +``` + +Added in v2.11.0 + +## getUnionSemigroup + +**Signature** + +```ts +export declare const getUnionSemigroup: (E: Eq) => Semigroup +``` + +Added in v2.11.0 + ## ~~array~~ Use small, specific instances instead. @@ -2087,6 +2363,62 @@ export declare const array: FunctorWithIndex1<'Array', number> & Added in v2.0.0 +# natural transformations + +## fromEither + +**Signature** + +```ts +export declare const fromEither: NaturalTransformation21<'Either', 'Array'> +``` + +Added in v2.11.0 + +## fromOption + +**Signature** + +```ts +export declare const fromOption: NaturalTransformation11<'Option', 'Array'> +``` + +Added in v2.11.0 + +# refinements + +## isEmpty + +Test whether an array is empty + +**Signature** + +```ts +export declare const isEmpty: (as: A[]) => as is [] +``` + +**Example** + +```ts +import { isEmpty } from 'fp-ts/Array' + +assert.strictEqual(isEmpty([]), true) +``` + +Added in v2.0.0 + +## isNonEmpty + +Test whether an array is non empty narrowing down the type to `NonEmptyArray` + +**Signature** + +```ts +export declare const isNonEmpty: (as: A[]) => as is NEA.NonEmptyArray +``` + +Added in v2.0.0 + # unsafe ## unsafeDeleteAt @@ -2189,7 +2521,7 @@ Delete the element at the specified index, creating a new array, or returning `N **Signature** ```ts -export declare const deleteAt: (i: number) => (as: A[]) => O.Option +export declare const deleteAt: (i: number) => (as: A[]) => Option ``` **Example** @@ -2239,6 +2571,30 @@ export declare const every: (predicate: Predicate) => (as: A[]) => boolean Added in v2.9.0 +## exists + +Alias of [`some`](#some) + +**Signature** + +```ts +export declare const exists: (predicate: Predicate) => (as: A[]) => as is NEA.NonEmptyArray +``` + +Added in v2.11.0 + +## filterE + +Filter values inside a context. + +**Signature** + +```ts +export declare const filterE: FilterE1<'Array'> +``` + +Added in v2.11.0 + ## findIndex Find the first index for which a predicate holds @@ -2298,7 +2654,7 @@ Insert an element at the specified index, creating a new array, or returning `No **Signature** ```ts -export declare const insertAt: (i: number, a: A) => (as: A[]) => O.Option> +export declare const insertAt: (i: number, a: A) => (as: A[]) => Option> ``` **Example** @@ -2312,26 +2668,6 @@ assert.deepStrictEqual(insertAt(2, 5)([1, 2, 3, 4]), some([1, 2, 5, 3, 4])) Added in v2.0.0 -## isEmpty - -Test whether an array is empty - -**Signature** - -```ts -export declare const isEmpty: (as: A[]) => boolean -``` - -**Example** - -```ts -import { isEmpty } from 'fp-ts/Array' - -assert.strictEqual(isEmpty([]), true) -``` - -Added in v2.0.0 - ## isOutOfBound Test whether an array contains a particular index @@ -2351,7 +2687,7 @@ This function provides a safe way to read a value at a particular index from an **Signature** ```ts -export declare const lookup: { (i: number): (as: A[]) => O.Option; (i: number, as: A[]): O.Option } +export declare const lookup: { (i: number): (as: A[]) => Option; (i: number, as: A[]): Option } ``` **Example** @@ -2375,7 +2711,7 @@ of bounds **Signature** ```ts -export declare const modifyAt: (i: number, f: (a: A) => A) => (as: A[]) => O.Option +export declare const modifyAt: (i: number, f: (a: A) => A) => (as: A[]) => Option ``` **Example** @@ -2450,7 +2786,7 @@ Change the element at the specified index, creating a new array, or returning `N **Signature** ```ts -export declare const updateAt: (i: number, a: A) => (as: A[]) => O.Option +export declare const updateAt: (i: number, a: A) => (as: A[]) => Option ``` **Example** diff --git a/docs/modules/Either.ts.md b/docs/modules/Either.ts.md index bb5750fc9..57be9c548 100644 --- a/docs/modules/Either.ts.md +++ b/docs/modules/Either.ts.md @@ -24,33 +24,6 @@ Added in v2.0.0

Table of contents

-- [Alt](#alt) - - [alt](#alt) - - [altW](#altw) -- [Apply](#apply) - - [ap](#ap) - - [apW](#apw) -- [Bifunctor](#bifunctor) - - [bimap](#bimap) - - [mapLeft](#mapleft) -- [Extend](#extend) - - [extend](#extend) -- [Foldable](#foldable) - - [foldMap](#foldmap) - - [reduce](#reduce) - - [reduceRight](#reduceright) -- [Functor](#functor) - - [map](#map) -- [Monad](#monad) - - [chain](#chain) - - [chainW](#chainw) -- [MonadThrow](#monadthrow) - - [throwError](#throwerror) -- [Pointed](#pointed) - - [of](#of) -- [Traversable](#traversable) - - [sequence](#sequence) - - [traverse](#traverse) - [combinators](#combinators) - [apFirst](#apfirst) - [apSecond](#apsecond) @@ -62,12 +35,12 @@ Added in v2.0.0 - [filterOrElseW](#filterorelsew) - [flap](#flap) - [flatten](#flatten) + - [flattenW](#flattenw) - [fromOptionK](#fromoptionk) - [orElse](#orelse) - [orElseW](#orelsew) - [swap](#swap) - [constructors](#constructors) - - [fromOption](#fromoption) - [fromPredicate](#frompredicate) - [left](#left) - [right](#right) @@ -80,24 +53,39 @@ Added in v2.0.0 - [getOrElseW](#getorelsew) - [match](#match) - [matchW](#matchw) -- [guards](#guards) - - [isLeft](#isleft) - - [isRight](#isright) +- [instance operations](#instance-operations) + - [alt](#alt) + - [altW](#altw) + - [ap](#ap) + - [apW](#apw) + - [bimap](#bimap) + - [chain](#chain) + - [chainW](#chainw) + - [extend](#extend) + - [foldMap](#foldmap) + - [map](#map) + - [mapLeft](#mapleft) + - [of](#of) + - [reduce](#reduce) + - [reduceRight](#reduceright) + - [sequence](#sequence) + - [throwError](#throwerror) + - [traverse](#traverse) - [instances](#instances) - - [Alt](#alt-1) + - [Alt](#alt) - [Applicative](#applicative) - - [Apply](#apply-1) - - [Bifunctor](#bifunctor-1) + - [Apply](#apply) + - [Bifunctor](#bifunctor) - [Chain](#chain) - [ChainRec](#chainrec) - - [Extend](#extend-1) - - [Foldable](#foldable-1) + - [Extend](#extend) + - [Foldable](#foldable) - [FromEither](#fromeither) - - [Functor](#functor-1) - - [Monad](#monad-1) - - [MonadThrow](#monadthrow-1) - - [Pointed](#pointed-1) - - [Traversable](#traversable-1) + - [Functor](#functor) + - [Monad](#monad) + - [MonadThrow](#monadthrow) + - [Pointed](#pointed) + - [Traversable](#traversable) - [URI](#uri) - [URI (type alias)](#uri-type-alias) - [getAltValidation](#getaltvalidation) @@ -125,7 +113,13 @@ Added in v2.0.0 - [Either (type alias)](#either-type-alias) - [Left (interface)](#left-interface) - [Right (interface)](#right-interface) +- [natural transformations](#natural-transformations) + - [fromOption](#fromoption) +- [refinements](#refinements) + - [isLeft](#isleft) + - [isRight](#isright) - [utils](#utils) + - [ApT](#apt) - [Do](#do) - [apS](#aps) - [apSW](#apsw) @@ -138,804 +132,739 @@ Added in v2.0.0 - [toError](#toerror) - [traverseArray](#traversearray) - [traverseArrayWithIndex](#traversearraywithindex) + - [traverseReadonlyArrayWithIndex](#traversereadonlyarraywithindex) + - [traverseReadonlyNonEmptyArrayWithIndex](#traversereadonlynonemptyarraywithindex) - [~~JsonArray~~ (interface)](#jsonarray-interface) - [~~JsonRecord~~ (interface)](#jsonrecord-interface) - [~~Json~~ (type alias)](#json-type-alias) --- -# Alt - -## alt - -Identifies an associative operation on a type constructor. It is similar to `Semigroup`, except that it applies to -types of kind `* -> *`. - -**Signature** - -```ts -export declare const alt: (that: Lazy>) => (fa: Either) => Either -``` +# combinators -Added in v2.0.0 +## apFirst -## altW +Combine two effectful actions, keeping only the result of the first. -Less strict version of [`alt`](#alt). +Derivable from `Apply`. **Signature** ```ts -export declare const altW: (that: Lazy>) => (fa: Either) => Either +export declare const apFirst: (second: Either) =>
(first: Either) => Either ``` -Added in v2.9.0 +Added in v2.0.0 -# Apply +## apSecond -## ap +Combine two effectful actions, keeping only the result of the second. -Apply a function to an argument under a type constructor. +Derivable from `Apply`. **Signature** ```ts -export declare const ap: (fa: Either) => (fab: Either B>) => Either +export declare const apSecond: (second: Either) => (first: Either) => Either ``` Added in v2.0.0 -## apW +## chainFirst -Less strict version of [`ap`](#ap). +Composes computations in sequence, using the return value of one computation to determine the next computation and +keeping only the result of the first. + +Derivable from `Chain`. **Signature** ```ts -export declare const apW: (fa: Either) => (fab: Either B>) => Either +export declare const chainFirst: (f: (a: A) => Either) => (ma: Either) => Either ``` -Added in v2.8.0 +Added in v2.0.0 -# Bifunctor +## chainFirstW -## bimap +Less strict version of [`chainFirst`](#chainfirst) -Map a pair of functions over the two type arguments of the bifunctor. +Derivable from `Chain`. **Signature** ```ts -export declare const bimap: (f: (e: E) => G, g: (a: A) => B) => (fa: Either) => Either +export declare const chainFirstW: ( + f: (a: A) => Either +) => (ma: Either) => Either ``` -Added in v2.0.0 - -## mapLeft +Added in v2.8.0 -Map a function over the first type argument of a bifunctor. +## chainOptionK **Signature** ```ts -export declare const mapLeft: (f: (e: E) => G) => (fa: Either) => Either +export declare const chainOptionK: ( + onNone: Lazy +) => (f: (a: A) => Option) => (ma: Either) => Either ``` -Added in v2.0.0 +Added in v2.11.0 -# Extend +## duplicate -## extend +Derivable from `Extend`. **Signature** ```ts -export declare const extend: (f: (wa: Either) => B) => (wa: Either) => Either +export declare const duplicate: (ma: Either) => Either> ``` Added in v2.0.0 -# Foldable - -## foldMap - -Map each element of the structure to a monoid, and combine the results. +## filterOrElse **Signature** ```ts -export declare const foldMap: (M: Monoid) => (f: (a: A) => M) => (fa: Either) => M +export declare const filterOrElse: { + (refinement: Refinement, onFalse: (a: A) => E): (ma: Either) => Either + (predicate: Predicate, onFalse: (a: A) => E): (mb: Either) => Either + (predicate: Predicate, onFalse: (a: A) => E): (ma: Either) => Either +} ``` **Example** ```ts -import { pipe } from 'fp-ts/function' import * as E from 'fp-ts/Either' -import * as S from 'fp-ts/string' - -const yell = (a: string) => `${a}!` - -assert.deepStrictEqual(pipe(E.right('a'), E.foldMap(S.Monoid)(yell)), 'a!') +import { pipe } from 'fp-ts/function' -assert.deepStrictEqual(pipe(E.left('e'), E.foldMap(S.Monoid)(yell)), S.Monoid.empty) +assert.deepStrictEqual( + pipe( + E.right(1), + E.filterOrElse( + (n) => n > 0, + () => 'error' + ) + ), + E.right(1) +) +assert.deepStrictEqual( + pipe( + E.right(-1), + E.filterOrElse( + (n) => n > 0, + () => 'error' + ) + ), + E.left('error') +) +assert.deepStrictEqual( + pipe( + E.left('a'), + E.filterOrElse( + (n) => n > 0, + () => 'error' + ) + ), + E.left('a') +) ``` Added in v2.0.0 -## reduce +## filterOrElseW -Left-associative fold of a structure. +Less strict version of [`filterOrElse`](#filterorelse). **Signature** ```ts -export declare const reduce: (b: B, f: (b: B, a: A) => B) => (fa: Either) => B +export declare const filterOrElseW: { + (refinement: Refinement, onFalse: (a: A) => E2): ( + ma: Either + ) => Either + (predicate: Predicate, onFalse: (a: A) => E2): (mb: Either) => Either + (predicate: Predicate, onFalse: (a: A) => E2): (ma: Either) => Either +} ``` -**Example** +Added in v2.9.0 -```ts -import { pipe } from 'fp-ts/function' -import * as E from 'fp-ts/Either' +## flap -const startWith = 'prefix' -const concat = (a: string, b: string) => `${a}:${b}` +Derivable from `Functor`. -assert.deepStrictEqual(pipe(E.right('a'), E.reduce(startWith, concat)), 'prefix:a') +**Signature** -assert.deepStrictEqual(pipe(E.left('e'), E.reduce(startWith, concat)), 'prefix') +```ts +export declare const flap: (a: A) => (fab: Either B>) => Either ``` -Added in v2.0.0 +Added in v2.10.0 -## reduceRight +## flatten -Right-associative fold of a structure. +The `flatten` function is the conventional monad join operator. It is used to remove one level of monadic structure, projecting its bound argument into the outer level. + +Derivable from `Chain`. **Signature** ```ts -export declare const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: Either) => B +export declare const flatten: (mma: Either>) => Either ``` **Example** ```ts -import { pipe } from 'fp-ts/function' import * as E from 'fp-ts/Either' -const startWith = 'postfix' -const concat = (a: string, b: string) => `${a}:${b}` - -assert.deepStrictEqual(pipe(E.right('a'), E.reduceRight(startWith, concat)), 'a:postfix') - -assert.deepStrictEqual(pipe(E.left('e'), E.reduceRight(startWith, concat)), 'postfix') +assert.deepStrictEqual(E.flatten(E.right(E.right('a'))), E.right('a')) +assert.deepStrictEqual(E.flatten(E.right(E.left('e'))), E.left('e')) +assert.deepStrictEqual(E.flatten(E.left('e')), E.left('e')) ``` Added in v2.0.0 -# Functor - -## map +## flattenW -`map` can be used to turn functions `(a: A) => B` into functions `(fa: F) => F` whose argument and return types -use the type constructor `F` to represent some computational context. +Less strict version of [`flatten`](#flatten). **Signature** ```ts -export declare const map: (f: (a: A) => B) => (fa: Either) => Either +export declare const flattenW: (mma: Either>) => Either ``` -Added in v2.0.0 - -# Monad - -## chain +Added in v2.11.0 -Composes computations in sequence, using the return value of one computation to determine the next computation. +## fromOptionK **Signature** ```ts -export declare const chain: (f: (a: A) => Either) => (ma: Either) => Either +export declare const fromOptionK: (onNone: Lazy) => (f: (...a: A) => Option) => (...a: A) => Either ``` -Added in v2.0.0 +Added in v2.10.0 -## chainW +## orElse -Less strict version of [`chain`](#chain). +Useful for recovering from errors. **Signature** ```ts -export declare const chainW: (f: (a: A) => Either) => (ma: Either) => Either +export declare const orElse: (onLeft: (e: E1) => Either) => (ma: Either) => Either ``` -Added in v2.6.0 +Added in v2.0.0 -# MonadThrow +## orElseW -## throwError +Less strict version of [`orElse`](#orelse). **Signature** ```ts -export declare const throwError: (e: E) => Either +export declare const orElseW: ( + onLeft: (e: E1) => Either +) => (ma: Either) => Either ``` -Added in v2.6.3 +Added in v2.10.0 -# Pointed +## swap -## of +Returns a `Right` if is a `Left` (and vice versa). **Signature** ```ts -export declare const of: (a: A) => Either +export declare const swap: (ma: Either) => Either ``` -Added in v2.7.0 - -# Traversable +Added in v2.0.0 -## sequence +# constructors -Evaluate each monadic action in the structure from left to right, and collect the results. +## fromPredicate **Signature** ```ts -export declare const sequence: Sequence2<'Either'> +export declare const fromPredicate: { + (refinement: Refinement, onFalse: (a: A) => E): (a: A) => Either + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => Either + (predicate: Predicate, onFalse: (a: A) => E): (a: A) => Either +} ``` **Example** ```ts +import { fromPredicate, left, right } from 'fp-ts/Either' import { pipe } from 'fp-ts/function' -import * as E from 'fp-ts/Either' -import * as O from 'fp-ts/Option' -assert.deepStrictEqual(pipe(E.right(O.some('a')), E.sequence(O.Applicative)), O.some(E.right('a'))) - -assert.deepStrictEqual(pipe(E.right(O.none), E.sequence(O.Applicative)), O.none) +assert.deepStrictEqual( + pipe( + 1, + fromPredicate( + (n) => n > 0, + () => 'error' + ) + ), + right(1) +) +assert.deepStrictEqual( + pipe( + -1, + fromPredicate( + (n) => n > 0, + () => 'error' + ) + ), + left('error') +) ``` -Added in v2.6.3 +Added in v2.0.0 -## traverse +## left -Map each element of a structure to an action, evaluate these actions from left to right, and collect the results. +Constructs a new `Either` holding a `Left` value. This usually represents a failure, due to the right-bias of this +structure. **Signature** ```ts -export declare const traverse: PipeableTraverse2<'Either'> -``` - -**Example** - -```ts -import { pipe } from 'fp-ts/function' -import * as RA from 'fp-ts/ReadonlyArray' -import * as E from 'fp-ts/Either' -import * as O from 'fp-ts/Option' - -assert.deepStrictEqual(pipe(E.right(['a']), E.traverse(O.Applicative)(RA.head)), O.some(E.right('a'))) - -assert.deepStrictEqual(pipe(E.right([]), E.traverse(O.Applicative)(RA.head)), O.none) +export declare const left: (e: E) => Either ``` -Added in v2.6.3 - -# combinators - -## apFirst +Added in v2.0.0 -Combine two effectful actions, keeping only the result of the first. +## right -Derivable from `Apply`. +Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias +of this structure. **Signature** ```ts -export declare const apFirst: (second: Either) => (first: Either) => Either +export declare const right: (a: A) => Either ``` Added in v2.0.0 -## apSecond - -Combine two effectful actions, keeping only the result of the second. +## ~~parseJSON~~ -Derivable from `Apply`. +Use [`parse`](./Json.ts.html#parse) instead. **Signature** ```ts -export declare const apSecond: (second: Either) => (first: Either) => Either +export declare function parseJSON(s: string, onError: (reason: unknown) => E): Either ``` Added in v2.0.0 -## chainFirst - -Composes computations in sequence, using the return value of one computation to determine the next computation and -keeping only the result of the first. +## ~~stringifyJSON~~ -Derivable from `Chain`. +Use [`stringify`](./Json.ts.html#stringify) instead. **Signature** ```ts -export declare const chainFirst: (f: (a: A) => Either) => (ma: Either) => Either +export declare const stringifyJSON: (u: unknown, onError: (reason: unknown) => E) => Either ``` Added in v2.0.0 -## chainFirstW +# destructors -Less strict version of [`chainFirst`](#chainfirst) +## fold -Derivable from `Chain`. +Alias of [`match`](#match). **Signature** ```ts -export declare const chainFirstW: ( - f: (a: A) => Either -) => (ma: Either) => Either +export declare const fold: (onLeft: (e: E) => B, onRight: (a: A) => B) => (ma: Either) => B ``` -Added in v2.8.0 +Added in v2.0.0 -## chainOptionK +## foldW + +Alias of [`matchW`](#matchw). **Signature** ```ts -export declare const chainOptionK: ( - onNone: Lazy -) => (f: (a: A) => Option) => (ma: Either) => Either +export declare const foldW: (onLeft: (e: E) => B, onRight: (a: A) => C) => (ma: Either) => B | C ``` Added in v2.10.0 -## duplicate - -Derivable from `Extend`. - -**Signature** - -```ts -export declare const duplicate: (ma: Either) => Either> -``` - -Added in v2.0.0 +## getOrElse -## filterOrElse +Returns the wrapped value if it's a `Right` or a default value if is a `Left`. **Signature** ```ts -export declare const filterOrElse: { - (refinement: Refinement, onFalse: (a: A) => E): (ma: Either) => Either - (predicate: Predicate, onFalse: (a: A) => E): (ma: Either) => Either -} +export declare const getOrElse: (onLeft: (e: E) => A) => (ma: Either) => A ``` **Example** ```ts -import { filterOrElse as filterOrElse, left, right } from 'fp-ts/Either' +import { getOrElse, left, right } from 'fp-ts/Either' import { pipe } from 'fp-ts/function' assert.deepStrictEqual( pipe( right(1), - filterOrElse( - (n) => n > 0, - () => 'error' - ) - ), - right(1) -) -assert.deepStrictEqual( - pipe( - right(-1), - filterOrElse( - (n) => n > 0, - () => 'error' - ) + getOrElse(() => 0) ), - left('error') + 1 ) assert.deepStrictEqual( pipe( - left('a'), - filterOrElse( - (n) => n > 0, - () => 'error' - ) + left('error'), + getOrElse(() => 0) ), - left('a') + 0 ) ``` Added in v2.0.0 -## filterOrElseW - -Less strict version of [`filterOrElse`](#filterorelse). - -**Signature** - -```ts -export declare const filterOrElseW: { - (refinement: Refinement, onFalse: (a: A) => E2): ( - ma: Either - ) => Either - (predicate: Predicate, onFalse: (a: A) => E2): (ma: Either) => Either -} -``` - -Added in v2.9.0 - -## flap +## getOrElseW -Derivable from `Functor`. +Less strict version of [`getOrElse`](#getorelse). **Signature** ```ts -export declare const flap: (a: A) => (fab: Either B>) => Either +export declare const getOrElseW: (onLeft: (e: E) => B) => (ma: Either) => B | A ``` -Added in v2.10.0 - -## flatten +Added in v2.6.0 -The `flatten` function is the conventional monad join operator. It is used to remove one level of monadic structure, projecting its bound argument into the outer level. +## match -Derivable from `Chain`. +Takes two functions and an `Either` value, if the value is a `Left` the inner value is applied to the first function, +if the value is a `Right` the inner value is applied to the second function. **Signature** ```ts -export declare const flatten: (mma: Either>) => Either +export declare const match: (onLeft: (e: E) => B, onRight: (a: A) => B) => (ma: Either) => B ``` **Example** ```ts -import * as E from 'fp-ts/Either' - -assert.deepStrictEqual(E.flatten(E.right(E.right('a'))), E.right('a')) -assert.deepStrictEqual(E.flatten(E.right(E.left('e'))), E.left('e')) -assert.deepStrictEqual(E.flatten(E.left('e')), E.left('e')) -``` - -Added in v2.0.0 +import { match, left, right } from 'fp-ts/Either' +import { pipe } from 'fp-ts/function' -## fromOptionK +function onLeft(errors: Array): string { + return `Errors: ${errors.join(', ')}` +} -**Signature** +function onRight(value: number): string { + return `Ok: ${value}` +} -```ts -export declare const fromOptionK: ( - onNone: Lazy -) => (f: (...a: A) => Option) => (...a: A) => Either +assert.strictEqual(pipe(right(1), match(onLeft, onRight)), 'Ok: 1') +assert.strictEqual(pipe(left(['error 1', 'error 2']), match(onLeft, onRight)), 'Errors: error 1, error 2') ``` Added in v2.10.0 -## orElse +## matchW -Useful for recovering from errors. +Less strict version of [`match`](#match). **Signature** ```ts -export declare const orElse: (onLeft: (e: E1) => Either) => (ma: Either) => Either +export declare const matchW: (onLeft: (e: E) => B, onRight: (a: A) => C) => (ma: Either) => B | C ``` -Added in v2.0.0 +Added in v2.10.0 -## orElseW +# instance operations -Less strict version of [`orElse`](#orelse). +## alt + +Identifies an associative operation on a type constructor. It is similar to `Semigroup`, except that it applies to +types of kind `* -> *`. **Signature** ```ts -export declare const orElseW: ( - onLeft: (e: E1) => Either -) => (ma: Either) => Either +export declare const alt: (that: Lazy>) => (fa: Either) => Either ``` -Added in v2.10.0 +Added in v2.0.0 -## swap +## altW -Returns a `Right` if is a `Left` (and vice versa). +Less strict version of [`alt`](#alt). **Signature** ```ts -export declare function swap(ma: Either): Either +export declare const altW: (that: Lazy>) => (fa: Either) => Either ``` -Added in v2.0.0 +Added in v2.9.0 -# constructors +## ap -## fromOption +Apply a function to an argument under a type constructor. **Signature** ```ts -export declare const fromOption: (onNone: Lazy) => (ma: Option) => Either -``` - -**Example** - -```ts -import { fromOption, left, right } from 'fp-ts/Either' -import { pipe } from 'fp-ts/function' -import { none, some } from 'fp-ts/Option' - -assert.deepStrictEqual( - pipe( - some(1), - fromOption(() => 'error') - ), - right(1) -) -assert.deepStrictEqual( - pipe( - none, - fromOption(() => 'error') - ), - left('error') -) +export declare const ap: (fa: Either) => (fab: Either B>) => Either ``` Added in v2.0.0 -## fromPredicate +## apW + +Less strict version of [`ap`](#ap). **Signature** ```ts -export declare const fromPredicate: { - (refinement: Refinement, onFalse: (a: A) => E): (a: A) => Either - (predicate: Predicate, onFalse: (a: A) => E): (a: A) => Either -} +export declare const apW: (fa: Either) => (fab: Either B>) => Either ``` -**Example** - -```ts -import { fromPredicate, left, right } from 'fp-ts/Either' -import { pipe } from 'fp-ts/function' +Added in v2.8.0 -assert.deepStrictEqual( - pipe( - 1, - fromPredicate( - (n) => n > 0, - () => 'error' - ) - ), - right(1) -) -assert.deepStrictEqual( - pipe( - -1, - fromPredicate( - (n) => n > 0, - () => 'error' - ) - ), - left('error') -) +## bimap + +Map a pair of functions over the two type arguments of the bifunctor. + +**Signature** + +```ts +export declare const bimap: (f: (e: E) => G, g: (a: A) => B) => (fa: Either) => Either ``` Added in v2.0.0 -## left +## chain -Constructs a new `Either` holding a `Left` value. This usually represents a failure, due to the right-bias of this -structure. +Composes computations in sequence, using the return value of one computation to determine the next computation. **Signature** ```ts -export declare const left: (e: E) => Either +export declare const chain: (f: (a: A) => Either) => (ma: Either) => Either ``` Added in v2.0.0 -## right +## chainW -Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias -of this structure. +Less strict version of [`chain`](#chain). **Signature** ```ts -export declare const right: (a: A) => Either +export declare const chainW: (f: (a: A) => Either) => (ma: Either) => Either ``` -Added in v2.0.0 - -## ~~parseJSON~~ +Added in v2.6.0 -Use [`parse`](./Json.ts.html#parse) instead. +## extend **Signature** ```ts -export declare function parseJSON(s: string, onError: (reason: unknown) => E): Either +export declare const extend: (f: (wa: Either) => B) => (wa: Either) => Either ``` Added in v2.0.0 -## ~~stringifyJSON~~ +## foldMap -Use [`stringify`](./Json.ts.html#stringify) instead. +Map each element of the structure to a monoid, and combine the results. **Signature** ```ts -export declare const stringifyJSON: (u: unknown, onError: (reason: unknown) => E) => Either +export declare const foldMap: (M: Monoid) => (f: (a: A) => M) => (fa: Either) => M ``` -Added in v2.0.0 +**Example** -# destructors +```ts +import { pipe } from 'fp-ts/function' +import * as E from 'fp-ts/Either' +import * as S from 'fp-ts/string' -## fold +const yell = (a: string) => `${a}!` -Alias of [`match`](#match). +assert.deepStrictEqual(pipe(E.right('a'), E.foldMap(S.Monoid)(yell)), 'a!') + +assert.deepStrictEqual(pipe(E.left('e'), E.foldMap(S.Monoid)(yell)), S.Monoid.empty) +``` + +Added in v2.0.0 + +## map **Signature** ```ts -export declare const fold: (onLeft: (e: E) => B, onRight: (a: A) => B) => (ma: Either) => B +export declare const map: (f: (a: A) => B) => (fa: Either) => Either ``` Added in v2.0.0 -## foldW +## mapLeft -Alias of [`matchW`](#matchww). +Map a function over the first type argument of a bifunctor. **Signature** ```ts -export declare const foldW: (onLeft: (e: E) => B, onRight: (a: A) => C) => (ma: Either) => B | C +export declare const mapLeft: (f: (e: E) => G) => (fa: Either) => Either ``` -Added in v2.10.0 +Added in v2.0.0 -## getOrElse +## of -Returns the wrapped value if it's a `Right` or a default value if is a `Left`. +**Signature** + +```ts +export declare const of: (a: A) => Either +``` + +Added in v2.7.0 + +## reduce + +Left-associative fold of a structure. **Signature** ```ts -export declare const getOrElse: (onLeft: (e: E) => A) => (ma: Either) => A +export declare const reduce: (b: B, f: (b: B, a: A) => B) => (fa: Either) => B ``` **Example** ```ts -import { getOrElse, left, right } from 'fp-ts/Either' import { pipe } from 'fp-ts/function' +import * as E from 'fp-ts/Either' -assert.deepStrictEqual( - pipe( - right(1), - getOrElse(() => 0) - ), - 1 -) -assert.deepStrictEqual( - pipe( - left('error'), - getOrElse(() => 0) - ), - 0 -) +const startWith = 'prefix' +const concat = (a: string, b: string) => `${a}:${b}` + +assert.deepStrictEqual(pipe(E.right('a'), E.reduce(startWith, concat)), 'prefix:a') + +assert.deepStrictEqual(pipe(E.left('e'), E.reduce(startWith, concat)), 'prefix') ``` Added in v2.0.0 -## getOrElseW +## reduceRight -Less strict version of [`getOrElse`](#getorelse). +Right-associative fold of a structure. **Signature** ```ts -export declare const getOrElseW: (onLeft: (e: E) => B) => (ma: Either) => B | A +export declare const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: Either) => B ``` -Added in v2.6.0 +**Example** -## match +```ts +import { pipe } from 'fp-ts/function' +import * as E from 'fp-ts/Either' -Takes two functions and an `Either` value, if the value is a `Left` the inner value is applied to the first function, -if the value is a `Right` the inner value is applied to the second function. +const startWith = 'postfix' +const concat = (a: string, b: string) => `${a}:${b}` + +assert.deepStrictEqual(pipe(E.right('a'), E.reduceRight(startWith, concat)), 'a:postfix') + +assert.deepStrictEqual(pipe(E.left('e'), E.reduceRight(startWith, concat)), 'postfix') +``` + +Added in v2.0.0 + +## sequence + +Evaluate each monadic action in the structure from left to right, and collect the results. **Signature** ```ts -export declare const match: (onLeft: (e: E) => B, onRight: (a: A) => B) => (ma: Either) => B +export declare const sequence: Sequence2<'Either'> ``` **Example** ```ts -import { match, left, right } from 'fp-ts/Either' import { pipe } from 'fp-ts/function' +import * as E from 'fp-ts/Either' +import * as O from 'fp-ts/Option' -function onLeft(errors: Array): string { - return `Errors: ${errors.join(', ')}` -} - -function onRight(value: number): string { - return `Ok: ${value}` -} +assert.deepStrictEqual(pipe(E.right(O.some('a')), E.sequence(O.Applicative)), O.some(E.right('a'))) -assert.strictEqual(pipe(right(1), match(onLeft, onRight)), 'Ok: 1') -assert.strictEqual(pipe(left(['error 1', 'error 2']), match(onLeft, onRight)), 'Errors: error 1, error 2') +assert.deepStrictEqual(pipe(E.right(O.none), E.sequence(O.Applicative)), O.none) ``` -Added in v2.10.0 - -## matchW +Added in v2.6.3 -Less strict version of [`match`](#match). +## throwError **Signature** ```ts -export declare const matchW: (onLeft: (e: E) => B, onRight: (a: A) => C) => (ma: Either) => B | C +export declare const throwError: (e: E) => Either ``` -Added in v2.10.0 - -# guards +Added in v2.6.3 -## isLeft +## traverse -Returns `true` if the either is an instance of `Left`, `false` otherwise. +Map each element of a structure to an action, evaluate these actions from left to right, and collect the results. **Signature** ```ts -export declare const isLeft: (ma: Either) => ma is Left +export declare const traverse: PipeableTraverse2<'Either'> ``` -Added in v2.0.0 - -## isRight +**Example** -Returns `true` if the either is an instance of `Right`, `false` otherwise. +```ts +import { pipe } from 'fp-ts/function' +import * as RA from 'fp-ts/ReadonlyArray' +import * as E from 'fp-ts/Either' +import * as O from 'fp-ts/Option' -**Signature** +assert.deepStrictEqual(pipe(E.right(['a']), E.traverse(O.Applicative)(RA.head)), O.some(E.right('a'))) -```ts -export declare const isRight: (ma: Either) => ma is Right +assert.deepStrictEqual(pipe(E.right([]), E.traverse(O.Applicative)(RA.head)), O.none) ``` -Added in v2.0.0 +Added in v2.6.3 # instances @@ -1104,7 +1033,7 @@ Added in v2.0.0 **Signature** ```ts -export declare function getAltValidation(SE: Semigroup): Alt2C +export declare const getAltValidation: (SE: Semigroup) => Alt2C<'Either', E> ``` Added in v2.7.0 @@ -1114,7 +1043,7 @@ Added in v2.7.0 **Signature** ```ts -export declare function getApplicativeValidation(SE: Semigroup): Applicative2C +export declare const getApplicativeValidation: (SE: Semigroup) => Applicative2C<'Either', E> ``` Added in v2.7.0 @@ -1136,7 +1065,7 @@ Added in v2.10.0 **Signature** ```ts -export declare function getEq(EL: Eq, EA: Eq): Eq> +export declare const getEq: (EL: Eq, EA: Eq) => Eq> ``` Added in v2.0.0 @@ -1148,7 +1077,7 @@ Builds a `Filterable` instance for `Either` given `Monoid` for the left side **Signature** ```ts -export declare function getFilterable(M: Monoid): Filterable2C +export declare const getFilterable: (M: Monoid) => Filterable2C<'Either', E> ``` Added in v2.10.0 @@ -1161,7 +1090,7 @@ concatenated using the provided `Semigroup` **Signature** ```ts -export declare function getSemigroup(S: Semigroup): Semigroup> +export declare const getSemigroup: (S: Semigroup) => Semigroup> ``` **Example** @@ -1184,7 +1113,7 @@ Added in v2.0.0 **Signature** ```ts -export declare function getShow(SE: Show, SA: Show): Show> +export declare const getShow: (SE: Show, SA: Show) => Show> ``` Added in v2.0.0 @@ -1196,7 +1125,7 @@ Builds `Witherable` instance for `Either` given `Monoid` for the left side **Signature** ```ts -export declare function getWitherable(M: Monoid): Witherable2C +export declare const getWitherable: (M: Monoid) => Witherable2C<'Either', E> ``` Added in v2.0.0 @@ -1442,8 +1371,79 @@ export interface Right { Added in v2.0.0 +# natural transformations + +## fromOption + +**Signature** + +```ts +export declare const fromOption: (onNone: Lazy) => NaturalTransformation12C<'Option', 'Either', E> +``` + +**Example** + +```ts +import * as E from 'fp-ts/Either' +import { pipe } from 'fp-ts/function' +import * as O from 'fp-ts/Option' + +assert.deepStrictEqual( + pipe( + O.some(1), + E.fromOption(() => 'error') + ), + E.right(1) +) +assert.deepStrictEqual( + pipe( + O.none, + E.fromOption(() => 'error') + ), + E.left('error') +) +``` + +Added in v2.0.0 + +# refinements + +## isLeft + +Returns `true` if the either is an instance of `Left`, `false` otherwise. + +**Signature** + +```ts +export declare const isLeft: (ma: Either) => ma is Left +``` + +Added in v2.0.0 + +## isRight + +Returns `true` if the either is an instance of `Right`, `false` otherwise. + +**Signature** + +```ts +export declare const isRight: (ma: Either) => ma is Right +``` + +Added in v2.0.0 + # utils +## ApT + +**Signature** + +```ts +export declare const ApT: Either +``` + +Added in v2.11.0 + ## Do **Signature** @@ -1521,7 +1521,7 @@ Added in v2.8.0 **Signature** ```ts -export declare function elem(E: Eq): (a: A, ma: Either) => boolean +export declare const elem: (E: Eq) => (a: A, ma: Either) => boolean ``` Added in v2.0.0 @@ -1533,7 +1533,7 @@ Returns `false` if `Left` or returns the result of the application of the given **Signature** ```ts -export declare function exists(predicate: Predicate): (ma: Either) => boolean +export declare const exists: (predicate: Predicate) => (ma: Either) => boolean ``` **Example** @@ -1552,8 +1552,6 @@ Added in v2.0.0 ## sequenceArray -Equivalent to `ReadonlyArray#sequence(Applicative)`. - **Signature** ```ts @@ -1576,8 +1574,6 @@ Added in v2.0.0 ## traverseArray -Equivalent to `ReadonlyArray#traverse(Applicative)`. - **Signature** ```ts @@ -1590,8 +1586,6 @@ Added in v2.9.0 ## traverseArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. - **Signature** ```ts @@ -1602,6 +1596,34 @@ export declare const traverseArrayWithIndex: ( Added in v2.9.0 +## traverseReadonlyArrayWithIndex + +Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndex: ( + f: (index: number, a: A) => Either +) => (as: readonly A[]) => Either +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndex + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndex: ( + f: (index: number, a: A) => Either +) => (as: ReadonlyNonEmptyArray) => Either> +``` + +Added in v2.11.0 + ## ~~JsonArray~~ (interface) Use [`Json`](./Json.ts.html) module instead. @@ -1622,7 +1644,6 @@ Use [`Json`](./Json.ts.html) module instead. ```ts export interface JsonRecord { - // tslint:disable-next-line: deprecation readonly [key: string]: Json } ``` diff --git a/docs/modules/EitherT.ts.md b/docs/modules/EitherT.ts.md index a8c785492..e1fcfcf1d 100644 --- a/docs/modules/EitherT.ts.md +++ b/docs/modules/EitherT.ts.md @@ -30,6 +30,8 @@ Added in v2.0.0 - [match](#match) - [matchE](#matche) - [orElse](#orelse) + - [orElseFirst](#orelsefirst) + - [orLeft](#orleft) - [right](#right) - [rightF](#rightf) - [swap](#swap) @@ -401,7 +403,7 @@ export declare function match( ): (onLeft: (e: E) => B, onRight: (a: A) => B) => (ma: HKT>) => HKT ``` -Added in v3.0.0 +Added in v2.11.0 ## matchE @@ -477,6 +479,74 @@ export declare function orElse( Added in v2.10.0 +## orElseFirst + +**Signature** + +```ts +export declare function orElseFirst( + M: Monad3 +): ( + onLeft: (e: E) => Kind3> +) => (ma: Kind3>) => Kind3> +export declare function orElseFirst( + M: Monad3C +): ( + onLeft: (e: E) => Kind3> +) => (ma: Kind3>) => Kind3> +export declare function orElseFirst( + M: Monad2 +): ( + onLeft: (e: E) => Kind2> +) => (ma: Kind2>) => Kind2> +export declare function orElseFirst( + M: Monad2C +): ( + onLeft: (e: E) => Kind2> +) => (ma: Kind2>) => Kind2> +export declare function orElseFirst( + M: Monad1 +): (onLeft: (e: E) => Kind>) => (ma: Kind>) => Kind> +export declare function orElseFirst( + M: Monad +): (onLeft: (e: E) => HKT>) => (ma: HKT>) => HKT> +``` + +Added in v2.11.0 + +## orLeft + +**Signature** + +```ts +export declare function orLeft( + M: Monad3 +): ( + onLeft: (e: E1) => Kind3 +) => (fa: Kind3>) => Kind3> +export declare function orLeft( + M: Monad3C +): ( + onLeft: (e: E1) => Kind3 +) => (fa: Kind3>) => Kind3> +export declare function orLeft( + M: Monad2 +): ( + onLeft: (e: E1) => Kind2 +) => (fa: Kind2>) => Kind2> +export declare function orLeft( + M: Monad2C +): (onLeft: (e: E1) => Kind2) => (fa: Kind2>) => Kind2> +export declare function orLeft( + M: Monad1 +): (onLeft: (e: E1) => Kind) => (fa: Kind>) => Kind> +export declare function orLeft( + M: Monad +): (onLeft: (e: E1) => HKT) => (fa: HKT>) => HKT> +``` + +Added in v2.11.0 + ## right **Signature** diff --git a/docs/modules/Endomorphism.ts.md b/docs/modules/Endomorphism.ts.md new file mode 100644 index 000000000..9e15125bf --- /dev/null +++ b/docs/modules/Endomorphism.ts.md @@ -0,0 +1,83 @@ +--- +title: Endomorphism.ts +nav_order: 27 +parent: Modules +--- + +## Endomorphism overview + +Added in v2.11.0 + +--- + +

Table of contents

+ +- [instances](#instances) + - [URI](#uri) + - [URI (type alias)](#uri-type-alias) + - [getMonoid](#getmonoid) + - [getSemigroup](#getsemigroup) +- [utils](#utils) + - [Endomorphism (interface)](#endomorphism-interface) + +--- + +# instances + +## URI + +**Signature** + +```ts +export declare const URI: 'Endomorphism' +``` + +Added in v2.11.0 + +## URI (type alias) + +**Signature** + +```ts +export type URI = typeof URI +``` + +Added in v2.11.0 + +## getMonoid + +Endomorphism form a `Monoid` where the `empty` value is the `identity` function. + +**Signature** + +```ts +export declare const getMonoid:
() => Monoid> +``` + +Added in v2.11.0 + +## getSemigroup + +Endomorphism form a `Semigroup` where the `concat` operation is the usual function composition. + +**Signature** + +```ts +export declare const getSemigroup: () => Semigroup> +``` + +Added in v2.11.0 + +# utils + +## Endomorphism (interface) + +**Signature** + +```ts +export interface Endomorphism { + (a: A): A +} +``` + +Added in v2.11.0 diff --git a/docs/modules/Eq.ts.md b/docs/modules/Eq.ts.md index 006a79297..4971123fd 100644 --- a/docs/modules/Eq.ts.md +++ b/docs/modules/Eq.ts.md @@ -1,6 +1,6 @@ --- title: Eq.ts -nav_order: 27 +nav_order: 28 parent: Modules --- @@ -132,7 +132,7 @@ Added in v2.0.0 **Signature** ```ts -export declare function fromEquals(equals: (x: A, y: A) => boolean): Eq +export declare const fromEquals: (equals: (x: A, y: A) => boolean) => Eq ``` Added in v2.0.0 diff --git a/docs/modules/Extend.ts.md b/docs/modules/Extend.ts.md index 6a2e8e342..fd190142d 100644 --- a/docs/modules/Extend.ts.md +++ b/docs/modules/Extend.ts.md @@ -1,6 +1,6 @@ --- title: Extend.ts -nav_order: 28 +nav_order: 29 parent: Modules --- diff --git a/docs/modules/Field.ts.md b/docs/modules/Field.ts.md index 27b6dff04..42acf1abf 100644 --- a/docs/modules/Field.ts.md +++ b/docs/modules/Field.ts.md @@ -1,6 +1,6 @@ --- title: Field.ts -nav_order: 29 +nav_order: 30 parent: Modules --- diff --git a/docs/modules/Filterable.ts.md b/docs/modules/Filterable.ts.md index 64976533a..b9e272eb3 100644 --- a/docs/modules/Filterable.ts.md +++ b/docs/modules/Filterable.ts.md @@ -1,6 +1,6 @@ --- title: Filterable.ts -nav_order: 30 +nav_order: 31 parent: Modules --- @@ -69,19 +69,35 @@ Added in v2.0.0 export declare function filter( F: Functor2, G: Filterable2C -): (predicate: Predicate) => (fga: Kind2>) => Kind2> +): { + (refinement: Refinement): (fga: Kind2>) => Kind2> + (predicate: Predicate): (fgb: Kind2>) => Kind2> + (predicate: Predicate): (fga: Kind2>) => Kind2> +} export declare function filter( F: Functor1, G: Filterable2C -): (predicate: Predicate) => (fga: Kind>) => Kind> +): { + (refinement: Refinement): (fga: Kind>) => Kind> + (predicate: Predicate): (fgb: Kind>) => Kind> + (predicate: Predicate): (fga: Kind>) => Kind> +} export declare function filter( F: Functor1, G: Filterable1 -): (predicate: Predicate) => (fga: Kind>) => Kind> +): { + (refinement: Refinement): (fga: Kind>) => Kind> + (predicate: Predicate): (fgb: Kind>) => Kind> + (predicate: Predicate): (fga: Kind>) => Kind> +} export declare function filter( F: Functor, G: Filterable -): (predicate: Predicate) => (fga: HKT>) => HKT> +): { + (refinement: Refinement): (fga: HKT>) => HKT> + (predicate: Predicate): (fgb: HKT>) => HKT> + (predicate: Predicate): (fga: HKT>) => HKT> +} ``` Added in v2.10.0 @@ -123,23 +139,53 @@ Added in v2.10.0 export declare function partition( F: Functor2, G: Filterable2C -): ( - predicate: Predicate -) => (fga: Kind2>) => Separated>, Kind2>> +): { + (refinement: Refinement): ( + fga: Kind2> + ) => Separated>, Kind2>> + (predicate: Predicate): ( + fgb: Kind2> + ) => Separated>, Kind2>> + (predicate: Predicate): ( + fga: Kind2> + ) => Separated>, Kind2>> +} export declare function partition( F: Functor1, G: Filterable2C -): ( - predicate: Predicate -) => (fga: Kind>) => Separated>, Kind>> +): { + (refinement: Refinement): ( + fga: Kind> + ) => Separated>, Kind>> + (predicate: Predicate): ( + fgb: Kind> + ) => Separated>, Kind>> + (predicate: Predicate): ( + fga: Kind> + ) => Separated>, Kind>> +} export declare function partition( F: Functor1, G: Filterable1 -): (predicate: Predicate) => (fga: Kind>) => Separated>, Kind>> +): { + (refinement: Refinement): ( + fga: Kind> + ) => Separated>, Kind>> + (predicate: Predicate): ( + fgb: Kind> + ) => Separated>, Kind>> + (predicate: Predicate): (fga: Kind>) => Separated>, Kind>> +} export declare function partition( F: Functor, G: Filterable -): (predicate: Predicate) => (fga: HKT>) => Separated>, HKT>> +): { + (refinement: Refinement): ( + fga: HKT> + ) => Separated>, HKT>> + (predicate: Predicate): (fgb: HKT>) => Separated>, HKT>> + (predicate: Predicate): (fga: HKT>) => Separated>, HKT>> +} ``` Added in v2.10.0 diff --git a/docs/modules/FilterableWithIndex.ts.md b/docs/modules/FilterableWithIndex.ts.md index 47600e2a1..d22e3bae6 100644 --- a/docs/modules/FilterableWithIndex.ts.md +++ b/docs/modules/FilterableWithIndex.ts.md @@ -1,6 +1,6 @@ --- title: FilterableWithIndex.ts -nav_order: 31 +nav_order: 32 parent: Modules --- diff --git a/docs/modules/Foldable.ts.md b/docs/modules/Foldable.ts.md index b5427ed7a..857514f78 100644 --- a/docs/modules/Foldable.ts.md +++ b/docs/modules/Foldable.ts.md @@ -1,6 +1,6 @@ --- title: Foldable.ts -nav_order: 32 +nav_order: 33 parent: Modules --- diff --git a/docs/modules/FoldableWithIndex.ts.md b/docs/modules/FoldableWithIndex.ts.md index 48f411f81..0f23ead2a 100644 --- a/docs/modules/FoldableWithIndex.ts.md +++ b/docs/modules/FoldableWithIndex.ts.md @@ -1,6 +1,6 @@ --- title: FoldableWithIndex.ts -nav_order: 33 +nav_order: 34 parent: Modules --- diff --git a/docs/modules/FromEither.ts.md b/docs/modules/FromEither.ts.md index 872385d0a..2186f0671 100644 --- a/docs/modules/FromEither.ts.md +++ b/docs/modules/FromEither.ts.md @@ -1,6 +1,6 @@ --- title: FromEither.ts -nav_order: 34 +nav_order: 35 parent: Modules --- @@ -14,107 +14,27 @@ Added in v2.10.0

Table of contents

+- [combinators](#combinators) + - [chainEitherK](#chaineitherk) + - [chainOptionK](#chainoptionk) + - [filterOrElse](#filterorelse) + - [fromEitherK](#fromeitherk) + - [fromOptionK](#fromoptionk) +- [constructors](#constructors) + - [fromOption](#fromoption) + - [fromPredicate](#frompredicate) - [type classes](#type-classes) - [FromEither (interface)](#fromeither-interface) + - [FromEither1 (interface)](#fromeither1-interface) - [FromEither2 (interface)](#fromeither2-interface) - [FromEither2C (interface)](#fromeither2c-interface) - [FromEither3 (interface)](#fromeither3-interface) - [FromEither3C (interface)](#fromeither3c-interface) - [FromEither4 (interface)](#fromeither4-interface) -- [utils](#utils) - - [chainEitherK](#chaineitherk) - - [chainOptionK](#chainoptionk) - - [filterOrElse](#filterorelse) - - [fromEitherK](#fromeitherk) - - [fromOption](#fromoption) - - [fromOptionK](#fromoptionk) - - [fromPredicate](#frompredicate) --- -# type classes - -## FromEither (interface) - -**Signature** - -```ts -export interface FromEither { - readonly URI: F - readonly fromEither: (e: Either) => HKT2 -} -``` - -Added in v2.10.0 - -## FromEither2 (interface) - -**Signature** - -```ts -export interface FromEither2 { - readonly URI: F - readonly fromEither: (e: Either) => Kind2 -} -``` - -Added in v2.10.0 - -## FromEither2C (interface) - -**Signature** - -```ts -export interface FromEither2C { - readonly URI: F - readonly _E: E - readonly fromEither:
(e: Either) => Kind2 -} -``` - -Added in v2.10.0 - -## FromEither3 (interface) - -**Signature** - -```ts -export interface FromEither3 { - readonly URI: F - readonly fromEither: (e: Either) => Kind3 -} -``` - -Added in v2.10.0 - -## FromEither3C (interface) - -**Signature** - -```ts -export interface FromEither3C { - readonly URI: F - readonly _E: E - readonly fromEither: (e: Either) => Kind3 -} -``` - -Added in v2.10.0 - -## FromEither4 (interface) - -**Signature** - -```ts -export interface FromEither4 { - readonly URI: F - readonly fromEither: (e: Either) => Kind4 -} -``` - -Added in v2.10.0 - -# utils +# combinators ## chainEitherK @@ -141,6 +61,10 @@ export declare function chainEitherK( F: FromEither2C, M: Chain2C ): (f: (a: A) => Either) => (ma: Kind2) => Kind2 +export declare function chainEitherK( + F: FromEither1, + M: Chain1 +): (f: (a: A) => Either) => (ma: Kind) => Kind export declare function chainEitherK( F: FromEither, M: Chain @@ -194,6 +118,9 @@ export declare function filterOrElse( (refinement: Refinement, onFalse: (a: A) => E): ( ma: Kind4 ) => Kind4 + (predicate: Predicate, onFalse: (a: A) => E): ( + mb: Kind4 + ) => Kind4 (predicate: Predicate, onFalse: (a: A) => E): (ma: Kind4) => Kind4 } export declare function filterOrElse( @@ -203,6 +130,7 @@ export declare function filterOrElse( (refinement: Refinement, onFalse: (a: A) => E): ( ma: Kind3 ) => Kind3 + (predicate: Predicate, onFalse: (a: A) => E): (mb: Kind3) => Kind3 (predicate: Predicate, onFalse: (a: A) => E): (ma: Kind3) => Kind3 } export declare function filterOrElse( @@ -210,6 +138,7 @@ export declare function filterOrElse( M: Chain3C ): { (refinement: Refinement, onFalse: (a: A) => E): (ma: Kind3) => Kind3 + (predicate: Predicate, onFalse: (a: A) => E): (mb: Kind3) => Kind3 (predicate: Predicate, onFalse: (a: A) => E): (ma: Kind3) => Kind3 } export declare function filterOrElse( @@ -217,6 +146,7 @@ export declare function filterOrElse( M: Chain2 ): { (refinement: Refinement, onFalse: (a: A) => E): (ma: Kind2) => Kind2 + (predicate: Predicate, onFalse: (a: A) => E): (mb: Kind2) => Kind2 (predicate: Predicate, onFalse: (a: A) => E): (ma: Kind2) => Kind2 } export declare function filterOrElse( @@ -224,6 +154,7 @@ export declare function filterOrElse( M: Chain2C ): { (refinement: Refinement, onFalse: (a: A) => E): (ma: Kind2) => Kind2 + (predicate: Predicate, onFalse: (a: A) => E): (mb: Kind2) => Kind2 (predicate: Predicate, onFalse: (a: A) => E): (ma: Kind2) => Kind2 } export declare function filterOrElse( @@ -231,6 +162,7 @@ export declare function filterOrElse( M: Chain ): { (refinement: Refinement, onFalse: (a: A) => E): (ma: HKT2) => HKT2 + (predicate: Predicate, onFalse: (a: A) => E): (mb: HKT2) => HKT2 (predicate: Predicate, onFalse: (a: A) => E): (ma: HKT2) => HKT2 } ``` @@ -257,6 +189,9 @@ export declare function fromEitherK( export declare function fromEitherK( F: FromEither2C ): , B>(f: (...a: A) => Either) => (...a: A) => Kind2 +export declare function fromEitherK( + F: FromEither1 +): , B>(f: (...a: A) => Either) => (...a: A) => Kind export declare function fromEitherK( F: FromEither ): , E, B>(f: (...a: A) => Either) => (...a: A) => HKT2 @@ -264,31 +199,6 @@ export declare function fromEitherK( Added in v2.10.0 -## fromOption - -**Signature** - -```ts -export declare function fromOption( - F: FromEither4 -): (onNone: Lazy) => (ma: Option) => Kind4 -export declare function fromOption( - F: FromEither3 -): (onNone: Lazy) => (ma: Option) => Kind3 -export declare function fromOption( - F: FromEither3C -): (onNone: Lazy) => (ma: Option) => Kind3 -export declare function fromOption( - F: FromEither2 -): (onNone: Lazy) => (ma: Option) => Kind2 -export declare function fromOption( - F: FromEither2C -): (onNone: Lazy) => (ma: Option) => Kind2 -export declare function fromOption(F: FromEither): (onNone: Lazy) => (ma: Option) => HKT2 -``` - -Added in v2.10.0 - ## fromOptionK **Signature** @@ -326,6 +236,33 @@ export declare function fromOptionK( Added in v2.10.0 +# constructors + +## fromOption + +**Signature** + +```ts +export declare function fromOption( + F: FromEither4 +): (onNone: Lazy) => NaturalTransformation14C +export declare function fromOption( + F: FromEither3 +): (onNone: Lazy) => NaturalTransformation13C +export declare function fromOption( + F: FromEither3C +): (onNone: Lazy) => NaturalTransformation13C +export declare function fromOption( + F: FromEither2 +): (onNone: Lazy) => NaturalTransformation12C +export declare function fromOption( + F: FromEither2C +): (onNone: Lazy) => NaturalTransformation12C +export declare function fromOption(F: FromEither): (onNone: Lazy) => (ma: Option) => HKT2 +``` + +Added in v2.10.0 + ## fromPredicate **Signature** @@ -335,38 +272,139 @@ export declare function fromPredicate( F: FromEither4 ): { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => Kind4 + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => Kind4 (predicate: Predicate, onFalse: (a: A) => E): (a: A) => Kind4 } export declare function fromPredicate( F: FromEither3 ): { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => Kind3 + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => Kind3 (predicate: Predicate, onFalse: (a: A) => E): (a: A) => Kind3 } export declare function fromPredicate( F: FromEither3C ): { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => Kind3 + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => Kind3 (predicate: Predicate, onFalse: (a: A) => E): (a: A) => Kind3 } export declare function fromPredicate( F: FromEither2 ): { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => Kind2 + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => Kind2 (predicate: Predicate, onFalse: (a: A) => E): (a: A) => Kind2 } export declare function fromPredicate( F: FromEither2C ): { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => Kind2 + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => Kind2 (predicate: Predicate, onFalse: (a: A) => E): (a: A) => Kind2 } export declare function fromPredicate( F: FromEither ): { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => HKT2 + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => HKT2 (predicate: Predicate, onFalse: (a: A) => E): (a: A) => HKT2 } ``` Added in v2.10.0 + +# type classes + +## FromEither (interface) + +**Signature** + +```ts +export interface FromEither { + readonly URI: F + readonly fromEither: (e: Either) => HKT2 +} +``` + +Added in v2.10.0 + +## FromEither1 (interface) + +**Signature** + +```ts +export interface FromEither1 { + readonly URI: F + readonly fromEither: NaturalTransformation21 +} +``` + +Added in v2.11.0 + +## FromEither2 (interface) + +**Signature** + +```ts +export interface FromEither2 { + readonly URI: F + readonly fromEither: NaturalTransformation22 +} +``` + +Added in v2.10.0 + +## FromEither2C (interface) + +**Signature** + +```ts +export interface FromEither2C { + readonly URI: F + readonly _E: E + readonly fromEither: NaturalTransformation22C +} +``` + +Added in v2.10.0 + +## FromEither3 (interface) + +**Signature** + +```ts +export interface FromEither3 { + readonly URI: F + readonly fromEither: NaturalTransformation23 +} +``` + +Added in v2.10.0 + +## FromEither3C (interface) + +**Signature** + +```ts +export interface FromEither3C { + readonly URI: F + readonly _E: E + readonly fromEither: NaturalTransformation23C +} +``` + +Added in v2.10.0 + +## FromEither4 (interface) + +**Signature** + +```ts +export interface FromEither4 { + readonly URI: F + readonly fromEither: NaturalTransformation24 +} +``` + +Added in v2.10.0 diff --git a/docs/modules/FromIO.ts.md b/docs/modules/FromIO.ts.md index 5d20e3ed6..431a980d4 100644 --- a/docs/modules/FromIO.ts.md +++ b/docs/modules/FromIO.ts.md @@ -1,6 +1,6 @@ --- title: FromIO.ts -nav_order: 35 +nav_order: 36 parent: Modules --- @@ -157,7 +157,7 @@ Added in v2.10.0 ```ts export interface FromIO1 { readonly URI: F - readonly fromIO: (fa: IO) => Kind + readonly fromIO: NaturalTransformation11 } ``` @@ -170,7 +170,7 @@ Added in v2.10.0 ```ts export interface FromIO2 { readonly URI: F - readonly fromIO: (fa: IO) => Kind2 + readonly fromIO: NaturalTransformation12 } ``` @@ -184,7 +184,7 @@ Added in v2.10.0 export interface FromIO2C { readonly URI: F readonly _E: E - readonly fromIO: (fa: IO) => Kind2 + readonly fromIO: NaturalTransformation12C } ``` @@ -197,7 +197,7 @@ Added in v2.10.0 ```ts export interface FromIO3 { readonly URI: F - readonly fromIO: (fa: IO) => Kind3 + readonly fromIO: NaturalTransformation13 } ``` @@ -211,7 +211,7 @@ Added in v2.10.0 export interface FromIO3C { readonly URI: F readonly _E: E - readonly fromIO: (fa: IO) => Kind3 + readonly fromIO: NaturalTransformation13C } ``` @@ -224,7 +224,7 @@ Added in v2.10.0 ```ts export interface FromIO4 { readonly URI: F - readonly fromIO: (fa: IO) => Kind4 + readonly fromIO: NaturalTransformation14 } ``` diff --git a/docs/modules/FromReader.ts.md b/docs/modules/FromReader.ts.md new file mode 100644 index 000000000..e71afbacd --- /dev/null +++ b/docs/modules/FromReader.ts.md @@ -0,0 +1,213 @@ +--- +title: FromReader.ts +nav_order: 37 +parent: Modules +--- + +## FromReader overview + +Lift a computation from the `Reader` monad. + +Added in v2.11.0 + +--- + +

Table of contents

+ +- [combinators](#combinators) + - [chainFirstReaderK](#chainfirstreaderk) + - [chainReaderK](#chainreaderk) + - [fromReaderK](#fromreaderk) +- [constructors](#constructors) + - [ask](#ask) + - [asks](#asks) +- [type classes](#type-classes) + - [FromReader (interface)](#fromreader-interface) + - [FromReader2 (interface)](#fromreader2-interface) + - [FromReader3 (interface)](#fromreader3-interface) + - [FromReader3C (interface)](#fromreader3c-interface) + - [FromReader4 (interface)](#fromreader4-interface) + +--- + +# combinators + +## chainFirstReaderK + +**Signature** + +```ts +export declare function chainFirstReaderK( + F: FromReader4, + M: Chain4 +): (f: (a: A) => Reader) => (ma: Kind4) => Kind4 +export declare function chainFirstReaderK( + F: FromReader3, + M: Chain3 +): (f: (a: A) => Reader) => (ma: Kind3) => Kind3 +export declare function chainFirstReaderK( + F: FromReader3C, + M: Chain3C +): (f: (a: A) => Reader) => (ma: Kind3) => Kind3 +export declare function chainFirstReaderK( + F: FromReader2, + M: Chain2 +): (f: (a: A) => Reader) => (ma: Kind2) => Kind2 +export declare function chainFirstReaderK( + F: FromReader, + M: Chain +): (f: (a: A) => Reader) => (ma: HKT2) => HKT2 +``` + +Added in v2.11.0 + +## chainReaderK + +**Signature** + +```ts +export declare function chainReaderK( + F: FromReader4, + M: Chain4 +): (f: (a: A) => Reader) => (ma: Kind4) => Kind4 +export declare function chainReaderK( + F: FromReader3, + M: Chain3 +): (f: (a: A) => Reader) => (ma: Kind3) => Kind3 +export declare function chainReaderK( + F: FromReader3C, + M: Chain3C +): (f: (a: A) => Reader) => (ma: Kind3) => Kind3 +export declare function chainReaderK( + F: FromReader2, + M: Chain2 +): (f: (a: A) => Reader) => (ma: Kind2) => Kind2 +export declare function chainReaderK( + F: FromReader, + M: Chain +): (f: (a: A) => Reader) => (ma: HKT2) => HKT2 +``` + +Added in v2.11.0 + +## fromReaderK + +**Signature** + +```ts +export declare function fromReaderK( + F: FromReader4 +):
, R, B>(f: (...a: A) => Reader) => (...a: A) => Kind4 +export declare function fromReaderK( + F: FromReader3 +): , R, B>(f: (...a: A) => Reader) => (...a: A) => Kind3 +export declare function fromReaderK( + F: FromReader3C +): , R, B>(f: (...a: A) => Reader) => (...a: A) => Kind3 +export declare function fromReaderK( + F: FromReader2 +): , R, B>(f: (...a: A) => Reader) => (...a: A) => Kind2 +export declare function fromReaderK( + F: FromReader +): , R, B>(f: (...a: A) => Reader) => (...a: A) => HKT2 +``` + +Added in v2.11.0 + +# constructors + +## ask + +**Signature** + +```ts +export declare function ask(F: FromReader4): () => Kind4 +export declare function ask(F: FromReader3): () => Kind3 +export declare function ask(F: FromReader3C): () => Kind3 +export declare function ask(F: FromReader2): () => Kind2 +export declare function ask(F: FromReader): () => HKT2 +``` + +Added in v2.11.0 + +## asks + +**Signature** + +```ts +export declare function asks(F: FromReader4): (f: (r: R) => A) => Kind4 +export declare function asks(F: FromReader3): (f: (r: R) => A) => Kind3 +export declare function asks(F: FromReader3C): (f: (r: R) => A) => Kind3 +export declare function asks(F: FromReader2): (f: (r: R) => A) => Kind2 +export declare function asks(F: FromReader): (f: (r: R) => A) => HKT2 +``` + +Added in v2.11.0 + +# type classes + +## FromReader (interface) + +**Signature** + +```ts +export interface FromReader { + readonly URI: F + readonly fromReader: (fa: Reader) => HKT2 +} +``` + +Added in v2.11.0 + +## FromReader2 (interface) + +**Signature** + +```ts +export interface FromReader2 { + readonly URI: F + readonly fromReader: NaturalTransformation22 +} +``` + +Added in v2.11.0 + +## FromReader3 (interface) + +**Signature** + +```ts +export interface FromReader3 { + readonly URI: F + readonly fromReader: NaturalTransformation23R +} +``` + +Added in v2.11.0 + +## FromReader3C (interface) + +**Signature** + +```ts +export interface FromReader3C { + readonly URI: F + readonly _E: E + readonly fromReader: NaturalTransformation23RC +} +``` + +Added in v2.11.0 + +## FromReader4 (interface) + +**Signature** + +```ts +export interface FromReader4 { + readonly URI: F + readonly fromReader: NaturalTransformation24R +} +``` + +Added in v2.11.0 diff --git a/docs/modules/FromState.ts.md b/docs/modules/FromState.ts.md new file mode 100644 index 000000000..122dc599b --- /dev/null +++ b/docs/modules/FromState.ts.md @@ -0,0 +1,213 @@ +--- +title: FromState.ts +nav_order: 38 +parent: Modules +--- + +## FromState overview + +Lift a computation from the `State` monad. + +Added in v2.11.0 + +--- + +

Table of contents

+ +- [combinators](#combinators) + - [chainStateK](#chainstatek) + - [fromStateK](#fromstatek) +- [constructors](#constructors) + - [get](#get) + - [gets](#gets) + - [modify](#modify) + - [put](#put) +- [type classes](#type-classes) + - [FromState (interface)](#fromstate-interface) + - [FromState2 (interface)](#fromstate2-interface) + - [FromState3 (interface)](#fromstate3-interface) + - [FromState3C (interface)](#fromstate3c-interface) + - [FromState4 (interface)](#fromstate4-interface) + +--- + +# combinators + +## chainStateK + +**Signature** + +```ts +export declare function chainStateK( + F: FromState4, + M: Chain4 +): (f: (a: A) => State) => (ma: Kind4) => Kind4 +export declare function chainStateK( + F: FromState3, + M: Chain3 +): (f: (a: A) => State) => (ma: Kind3) => Kind3 +export declare function chainStateK( + F: FromState2, + M: Chain2 +): (f: (a: A) => State) => (ma: Kind2) => Kind2 +export declare function chainStateK( + F: FromState, + M: Chain +): (f: (a: A) => State) => (ma: HKT2) => HKT2 +``` + +Added in v2.11.0 + +## fromStateK + +**Signature** + +```ts +export declare function fromStateK( + F: FromState4 +):
, S, B>(f: (...a: A) => State) => (...a: A) => Kind4 +export declare function fromStateK( + F: FromState3 +): , S, B>(f: (...a: A) => State) => (...a: A) => Kind3 +export declare function fromStateK( + F: FromState3C +): , S, B>(f: (...a: A) => State) => (...a: A) => Kind3 +export declare function fromStateK( + F: FromState2 +): , S, B>(f: (...a: A) => State) => (...a: A) => Kind2 +export declare function fromStateK( + F: FromState +): , S, B>(f: (...a: A) => State) => (...a: A) => HKT2 +``` + +Added in v2.11.0 + +# constructors + +## get + +**Signature** + +```ts +export declare function get(F: FromState4): () => Kind4 +export declare function get(F: FromState3): () => Kind3 +export declare function get(F: FromState3C): () => Kind3 +export declare function get(F: FromState2): () => Kind2 +export declare function get(F: FromState): () => HKT2 +``` + +Added in v2.11.0 + +## gets + +**Signature** + +```ts +export declare function gets(F: FromState4): (f: (s: S) => A) => Kind4 +export declare function gets(F: FromState3): (f: (s: S) => A) => Kind3 +export declare function gets(F: FromState3C): (f: (s: S) => A) => Kind3 +export declare function gets(F: FromState2): (f: (s: S) => A) => Kind2 +export declare function gets(F: FromState): (f: (s: S) => A) => HKT2 +``` + +Added in v2.11.0 + +## modify + +**Signature** + +```ts +export declare function modify( + F: FromState4 +): (f: Endomorphism) => Kind4 +export declare function modify(F: FromState3): (f: Endomorphism) => Kind3 +export declare function modify( + F: FromState3C +): (f: Endomorphism) => Kind3 +export declare function modify(F: FromState2): (f: Endomorphism) => Kind2 +export declare function modify(F: FromState): (f: Endomorphism) => HKT2 +``` + +Added in v2.11.0 + +## put + +**Signature** + +```ts +export declare function put(F: FromState4): (s: S) => Kind4 +export declare function put(F: FromState3): (s: S) => Kind3 +export declare function put(F: FromState3C): (s: S) => Kind3 +export declare function put(F: FromState2): (s: S) => Kind2 +export declare function put(F: FromState): (s: S) => HKT2 +``` + +Added in v2.11.0 + +# type classes + +## FromState (interface) + +**Signature** + +```ts +export interface FromState { + readonly URI: F + readonly fromState: (fa: State) => HKT2 +} +``` + +Added in v2.11.0 + +## FromState2 (interface) + +**Signature** + +```ts +export interface FromState2 { + readonly URI: F + readonly fromState: NaturalTransformation22 +} +``` + +Added in v2.11.0 + +## FromState3 (interface) + +**Signature** + +```ts +export interface FromState3 { + readonly URI: F + readonly fromState: NaturalTransformation23R +} +``` + +Added in v2.11.0 + +## FromState3C (interface) + +**Signature** + +```ts +export interface FromState3C { + readonly URI: F + readonly _E: E + readonly fromState: NaturalTransformation23RC +} +``` + +Added in v2.11.0 + +## FromState4 (interface) + +**Signature** + +```ts +export interface FromState4 { + readonly URI: F + readonly fromState: NaturalTransformation24S +} +``` + +Added in v2.11.0 diff --git a/docs/modules/FromTask.ts.md b/docs/modules/FromTask.ts.md index 8703453f1..67bc379be 100644 --- a/docs/modules/FromTask.ts.md +++ b/docs/modules/FromTask.ts.md @@ -1,6 +1,6 @@ --- title: FromTask.ts -nav_order: 36 +nav_order: 39 parent: Modules --- @@ -155,7 +155,7 @@ Added in v2.10.0 ```ts export interface FromTask1 extends FromIO1 { - readonly fromTask: (fa: Task) => Kind + readonly fromTask: NaturalTransformation11 } ``` @@ -167,7 +167,7 @@ Added in v2.10.0 ```ts export interface FromTask2 extends FromIO2 { - readonly fromTask: (fa: Task) => Kind2 + readonly fromTask: NaturalTransformation12 } ``` @@ -179,7 +179,7 @@ Added in v2.10.0 ```ts export interface FromTask2C extends FromIO2C { - readonly fromTask: (fa: Task) => Kind2 + readonly fromTask: NaturalTransformation12C } ``` @@ -191,7 +191,7 @@ Added in v2.10.0 ```ts export interface FromTask3 extends FromIO3 { - readonly fromTask: (fa: Task) => Kind3 + readonly fromTask: NaturalTransformation13 } ``` @@ -203,7 +203,7 @@ Added in v2.10.0 ```ts export interface FromTask3C extends FromIO3C { - readonly fromTask: (fa: Task) => Kind3 + readonly fromTask: NaturalTransformation13C } ``` @@ -215,7 +215,7 @@ Added in v2.10.0 ```ts export interface FromTask4 extends FromIO4 { - readonly fromTask: (fa: Task) => Kind4 + readonly fromTask: NaturalTransformation14 } ``` diff --git a/docs/modules/FromThese.ts.md b/docs/modules/FromThese.ts.md new file mode 100644 index 000000000..41ee328a0 --- /dev/null +++ b/docs/modules/FromThese.ts.md @@ -0,0 +1,138 @@ +--- +title: FromThese.ts +nav_order: 40 +parent: Modules +--- + +## FromThese overview + +The `FromThese` type class represents those data types which support errors and warnings. + +Added in v2.11.0 + +--- + +

Table of contents

+ +- [combinators](#combinators) + - [fromTheseK](#fromthesek) +- [type classes](#type-classes) + - [FromThese (interface)](#fromthese-interface) + - [FromThese2 (interface)](#fromthese2-interface) + - [FromThese2C (interface)](#fromthese2c-interface) + - [FromThese3 (interface)](#fromthese3-interface) + - [FromThese3C (interface)](#fromthese3c-interface) + - [FromThese4 (interface)](#fromthese4-interface) + +--- + +# combinators + +## fromTheseK + +**Signature** + +```ts +export declare function fromTheseK( + F: FromThese4 +):
, E, B>(f: (...a: A) => These) => (...a: A) => Kind4 +export declare function fromTheseK( + F: FromThese3 +): , E, B>(f: (...a: A) => These) => (...a: A) => Kind3 +export declare function fromTheseK( + F: FromThese3C +): , B>(f: (...a: A) => These) => (...a: A) => Kind3 +export declare function fromTheseK( + F: FromThese2 +): , E, B>(f: (...a: A) => These) => (...a: A) => Kind2 +export declare function fromTheseK( + F: FromThese2C +): , B>(f: (...a: A) => These) => (...a: A) => Kind2 +export declare function fromTheseK( + F: FromThese +): , E, B>(f: (...a: A) => These) => (...a: A) => HKT2 +``` + +Added in v2.11.0 + +# type classes + +## FromThese (interface) + +**Signature** + +```ts +export interface FromThese { + readonly URI: F + readonly fromThese: (e: These) => HKT2 +} +``` + +Added in v2.11.0 + +## FromThese2 (interface) + +**Signature** + +```ts +export interface FromThese2 { + readonly URI: F + readonly fromThese: NaturalTransformation22 +} +``` + +Added in v2.11.0 + +## FromThese2C (interface) + +**Signature** + +```ts +export interface FromThese2C { + readonly URI: F + readonly _E: E + readonly fromThese: NaturalTransformation22C +} +``` + +Added in v2.11.0 + +## FromThese3 (interface) + +**Signature** + +```ts +export interface FromThese3 { + readonly URI: F + readonly fromThese: NaturalTransformation23 +} +``` + +Added in v2.11.0 + +## FromThese3C (interface) + +**Signature** + +```ts +export interface FromThese3C { + readonly URI: F + readonly _E: E + readonly fromThese: NaturalTransformation23C +} +``` + +Added in v2.11.0 + +## FromThese4 (interface) + +**Signature** + +```ts +export interface FromThese4 { + readonly URI: F + readonly fromThese: NaturalTransformation24 +} +``` + +Added in v2.11.0 diff --git a/docs/modules/Functor.ts.md b/docs/modules/Functor.ts.md index 8c82bc8fe..50dd0293a 100644 --- a/docs/modules/Functor.ts.md +++ b/docs/modules/Functor.ts.md @@ -1,6 +1,6 @@ --- title: Functor.ts -nav_order: 38 +nav_order: 42 parent: Modules --- diff --git a/docs/modules/FunctorWithIndex.ts.md b/docs/modules/FunctorWithIndex.ts.md index c48b1fae6..db6b276ab 100644 --- a/docs/modules/FunctorWithIndex.ts.md +++ b/docs/modules/FunctorWithIndex.ts.md @@ -1,6 +1,6 @@ --- title: FunctorWithIndex.ts -nav_order: 39 +nav_order: 43 parent: Modules --- diff --git a/docs/modules/Group.ts.md b/docs/modules/Group.ts.md index fff59eb6d..8cf13c3a8 100644 --- a/docs/modules/Group.ts.md +++ b/docs/modules/Group.ts.md @@ -1,6 +1,6 @@ --- title: Group.ts -nav_order: 40 +nav_order: 44 parent: Modules --- diff --git a/docs/modules/HKT.ts.md b/docs/modules/HKT.ts.md index 8c53f62f5..ac7b0173b 100644 --- a/docs/modules/HKT.ts.md +++ b/docs/modules/HKT.ts.md @@ -1,6 +1,6 @@ --- title: HKT.ts -nav_order: 42 +nav_order: 46 parent: Modules --- diff --git a/docs/modules/HeytingAlgebra.ts.md b/docs/modules/HeytingAlgebra.ts.md index 8e972f030..43d64d111 100644 --- a/docs/modules/HeytingAlgebra.ts.md +++ b/docs/modules/HeytingAlgebra.ts.md @@ -1,6 +1,6 @@ --- title: HeytingAlgebra.ts -nav_order: 41 +nav_order: 45 parent: Modules --- diff --git a/docs/modules/IO.ts.md b/docs/modules/IO.ts.md index d8773e3da..0ff85e840 100644 --- a/docs/modules/IO.ts.md +++ b/docs/modules/IO.ts.md @@ -1,6 +1,6 @@ --- title: IO.ts -nav_order: 47 +nav_order: 51 parent: Modules --- @@ -56,6 +56,7 @@ Added in v2.0.0 - [model](#model) - [IO (interface)](#io-interface) - [utils](#utils) + - [ApT](#apt) - [Do](#do) - [apS](#aps) - [bind](#bind) @@ -63,6 +64,8 @@ Added in v2.0.0 - [sequenceArray](#sequencearray) - [traverseArray](#traversearray) - [traverseArrayWithIndex](#traversearraywithindex) + - [traverseReadonlyArrayWithIndex](#traversereadonlyarraywithindex) + - [traverseReadonlyNonEmptyArrayWithIndex](#traversereadonlynonemptyarraywithindex) --- @@ -197,7 +200,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const fromIO: (fa: IO) => IO +export declare const fromIO: NaturalTransformation11<'IO', 'IO'> ``` Added in v2.7.0 @@ -366,6 +369,16 @@ Added in v2.0.0 # utils +## ApT + +**Signature** + +```ts +export declare const ApT: IO +``` + +Added in v2.11.0 + ## Do **Signature** @@ -414,8 +427,6 @@ Added in v2.8.0 ## sequenceArray -Equivalent to `ReadonlyArray#sequence(Applicative)`. - **Signature** ```ts @@ -426,8 +437,6 @@ Added in v2.9.0 ## traverseArray -Equivalent to `ReadonlyArray#traverse(Applicative)`. - **Signature** ```ts @@ -438,8 +447,6 @@ Added in v2.9.0 ## traverseArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. - **Signature** ```ts @@ -449,3 +456,31 @@ export declare const traverseArrayWithIndex: ( ``` Added in v2.9.0 + +## traverseReadonlyArrayWithIndex + +Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndex: ( + f: (index: number, a: A) => IO +) => (as: readonly A[]) => IO +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndex + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndex: ( + f: (index: number, a: A) => IO +) => (as: ReadonlyNonEmptyArray) => IO> +``` + +Added in v2.11.0 diff --git a/docs/modules/IOEither.ts.md b/docs/modules/IOEither.ts.md index 277c95066..acac84ef0 100644 --- a/docs/modules/IOEither.ts.md +++ b/docs/modules/IOEither.ts.md @@ -1,6 +1,6 @@ --- title: IOEither.ts -nav_order: 48 +nav_order: 52 parent: Modules --- @@ -47,16 +47,17 @@ Added in v2.0.0 - [filterOrElseW](#filterorelsew) - [flap](#flap) - [flatten](#flatten) + - [flattenW](#flattenw) - [fromEitherK](#fromeitherk) - [fromIOK](#fromiok) - [fromOptionK](#fromoptionk) - [orElse](#orelse) + - [orElseFirst](#orelsefirst) + - [orElseFirstW](#orelsefirstw) - [orElseW](#orelsew) + - [orLeft](#orleft) - [swap](#swap) - [constructors](#constructors) - - [fromEither](#fromeither) - - [fromIO](#fromio) - - [fromOption](#fromoption) - [fromPredicate](#frompredicate) - [left](#left) - [leftIO](#leftio) @@ -103,7 +104,12 @@ Added in v2.0.0 - [tryCatchK](#trycatchk) - [model](#model) - [IOEither (interface)](#ioeither-interface) +- [natural transformations](#natural-transformations) + - [fromEither](#fromeither) + - [fromIO](#fromio) + - [fromOption](#fromoption) - [utils](#utils) + - [ApT](#apt) - [Do](#do) - [apS](#aps) - [apSW](#apsw) @@ -115,6 +121,10 @@ Added in v2.0.0 - [sequenceSeqArray](#sequenceseqarray) - [traverseArray](#traversearray) - [traverseArrayWithIndex](#traversearraywithindex) + - [traverseReadonlyArrayWithIndex](#traversereadonlyarraywithindex) + - [traverseReadonlyArrayWithIndexSeq](#traversereadonlyarraywithindexseq) + - [traverseReadonlyNonEmptyArrayWithIndex](#traversereadonlynonemptyarraywithindex) + - [traverseReadonlyNonEmptyArrayWithIndexSeq](#traversereadonlynonemptyarraywithindexseq) - [traverseSeqArray](#traverseseqarray) - [traverseSeqArrayWithIndex](#traverseseqarraywithindex) @@ -392,6 +402,7 @@ Added in v2.10.0 ```ts export declare const filterOrElse: { (refinement: Refinement, onFalse: (a: A) => E): (ma: IOEither) => IOEither + (predicate: Predicate, onFalse: (a: A) => E): (mb: IOEither) => IOEither (predicate: Predicate, onFalse: (a: A) => E): (ma: IOEither) => IOEither } ``` @@ -409,6 +420,9 @@ export declare const filterOrElseW: { (refinement: Refinement, onFalse: (a: A) => E2): ( ma: IOEither ) => IOEither + (predicate: Predicate, onFalse: (a: A) => E2): ( + mb: IOEither + ) => IOEither (predicate: Predicate, onFalse: (a: A) => E2): (ma: IOEither) => IOEither } ``` @@ -439,6 +453,18 @@ export declare const flatten: (mma: IOEither>) => IOEith Added in v2.0.0 +## flattenW + +Less strict version of [`flatten`](#flatten). + +**Signature** + +```ts +export declare const flattenW: (mma: IOEither>) => IOEither +``` + +Added in v2.11.0 + ## fromEitherK **Signature** @@ -483,62 +509,64 @@ export declare const orElse: (onLeft: (e: E1) => IOEither) => Added in v2.0.0 -## orElseW - -Less strict version of [`orElse`](#orelse). +## orElseFirst **Signature** ```ts -export declare const orElseW: ( - onLeft: (e: E1) => IOEither -) => (ma: IOEither) => IOEither +export declare const orElseFirst: (onLeft: (e: E) => IOEither) => (ma: IOEither) => IOEither ``` -Added in v2.10.0 +Added in v2.11.0 -## swap +## orElseFirstW **Signature** ```ts -export declare const swap: (ma: IOEither) => IOEither +export declare const orElseFirstW: ( + onLeft: (e: E1) => IOEither +) => (ma: IOEither) => IOEither ``` -Added in v2.0.0 +Added in v2.11.0 -# constructors +## orElseW -## fromEither +Less strict version of [`orElse`](#orelse). **Signature** ```ts -export declare const fromEither: (e: E.Either) => IOEither +export declare const orElseW: ( + onLeft: (e: E1) => IOEither +) => (ma: IOEither) => IOEither ``` -Added in v2.0.0 +Added in v2.10.0 -## fromIO +## orLeft **Signature** ```ts -export declare const fromIO: (fa: I.IO) => IOEither +export declare const orLeft: (onLeft: (e: E1) => I.IO) => (fa: IOEither) => IOEither ``` -Added in v2.7.0 +Added in v2.11.0 -## fromOption +## swap **Signature** ```ts -export declare const fromOption: (onNone: Lazy) => (ma: Option) => IOEither +export declare const swap: (ma: IOEither) => IOEither ``` Added in v2.0.0 +# constructors + ## fromPredicate **Signature** @@ -546,6 +574,7 @@ Added in v2.0.0 ```ts export declare const fromPredicate: { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => IOEither + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => IOEither (predicate: Predicate, onFalse: (a: A) => E): (a: A) => IOEither } ``` @@ -1022,8 +1051,50 @@ export interface IOEither extends IO> {} Added in v2.0.0 +# natural transformations + +## fromEither + +**Signature** + +```ts +export declare const fromEither: NaturalTransformation22<'Either', 'IOEither'> +``` + +Added in v2.0.0 + +## fromIO + +**Signature** + +```ts +export declare const fromIO: NaturalTransformation12<'IO', 'IOEither'> +``` + +Added in v2.7.0 + +## fromOption + +**Signature** + +```ts +export declare const fromOption: (onNone: Lazy) => NaturalTransformation12C<'Option', 'IOEither', E> +``` + +Added in v2.0.0 + # utils +## ApT + +**Signature** + +```ts +export declare const ApT: IOEither +``` + +Added in v2.11.0 + ## Do **Signature** @@ -1117,8 +1188,6 @@ Added in v2.0.0 ## sequenceArray -Equivalent to `ReadonlyArray#sequence(Applicative)`. - **Signature** ```ts @@ -1129,8 +1198,6 @@ Added in v2.9.0 ## sequenceSeqArray -Equivalent to `ReadonlyArray#sequence(ApplicativeSeq)`. - **Signature** ```ts @@ -1141,8 +1208,6 @@ Added in v2.9.0 ## traverseArray -Equivalent to `ReadonlyArray#traverse(Applicative)`. - **Signature** ```ts @@ -1155,8 +1220,6 @@ Added in v2.9.0 ## traverseArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. - **Signature** ```ts @@ -1167,9 +1230,63 @@ export declare const traverseArrayWithIndex: ( Added in v2.9.0 -## traverseSeqArray +## traverseReadonlyArrayWithIndex + +Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndex: ( + f: (index: number, a: A) => IOEither +) => (as: readonly A[]) => IOEither +``` + +Added in v2.11.0 -Equivalent to `ReadonlyArray#traverse(ApplicativeSeq)`. +## traverseReadonlyArrayWithIndexSeq + +Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndexSeq: ( + f: (index: number, a: A) => IOEither +) => (as: readonly A[]) => IOEither +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndex + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativePar)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndex: ( + f: (index: number, a: A) => IOEither +) => (as: ReadonlyNonEmptyArray) => IOEither> +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndexSeq + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativeSeq)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndexSeq: ( + f: (index: number, a: A) => IOEither +) => (as: ReadonlyNonEmptyArray) => IOEither> +``` + +Added in v2.11.0 + +## traverseSeqArray **Signature** @@ -1183,8 +1300,6 @@ Added in v2.9.0 ## traverseSeqArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. - **Signature** ```ts diff --git a/docs/modules/IORef.ts.md b/docs/modules/IORef.ts.md index 41971d360..91ce43431 100644 --- a/docs/modules/IORef.ts.md +++ b/docs/modules/IORef.ts.md @@ -1,6 +1,6 @@ --- title: IORef.ts -nav_order: 49 +nav_order: 53 parent: Modules --- diff --git a/docs/modules/Identity.ts.md b/docs/modules/Identity.ts.md index d2d0da92f..83867242f 100644 --- a/docs/modules/Identity.ts.md +++ b/docs/modules/Identity.ts.md @@ -1,6 +1,6 @@ --- title: Identity.ts -nav_order: 43 +nav_order: 47 parent: Modules --- diff --git a/docs/modules/Invariant.ts.md b/docs/modules/Invariant.ts.md index afe392670..343d99274 100644 --- a/docs/modules/Invariant.ts.md +++ b/docs/modules/Invariant.ts.md @@ -1,6 +1,6 @@ --- title: Invariant.ts -nav_order: 46 +nav_order: 50 parent: Modules --- diff --git a/docs/modules/JoinSemilattice.ts.md b/docs/modules/JoinSemilattice.ts.md index 5c277b169..9c808f292 100644 --- a/docs/modules/JoinSemilattice.ts.md +++ b/docs/modules/JoinSemilattice.ts.md @@ -1,6 +1,6 @@ --- title: JoinSemilattice.ts -nav_order: 50 +nav_order: 54 parent: Modules --- diff --git a/docs/modules/Json.ts.md b/docs/modules/Json.ts.md index 49f44417b..2ecbffff8 100644 --- a/docs/modules/Json.ts.md +++ b/docs/modules/Json.ts.md @@ -1,6 +1,6 @@ --- title: Json.ts -nav_order: 51 +nav_order: 55 parent: Modules --- diff --git a/docs/modules/Lattice.ts.md b/docs/modules/Lattice.ts.md index 41278efcd..0bd0479d3 100644 --- a/docs/modules/Lattice.ts.md +++ b/docs/modules/Lattice.ts.md @@ -1,6 +1,6 @@ --- title: Lattice.ts -nav_order: 52 +nav_order: 56 parent: Modules --- diff --git a/docs/modules/Magma.ts.md b/docs/modules/Magma.ts.md index 183e41898..8664a12a1 100644 --- a/docs/modules/Magma.ts.md +++ b/docs/modules/Magma.ts.md @@ -1,6 +1,6 @@ --- title: Magma.ts -nav_order: 53 +nav_order: 57 parent: Modules --- @@ -16,11 +16,73 @@ Added in v2.0.0

Table of contents

+- [combinators](#combinators) + - [endo](#endo) + - [filterFirst](#filterfirst) + - [filterSecond](#filtersecond) + - [reverse](#reverse) - [type classes](#type-classes) - [Magma (interface)](#magma-interface) +- [utils](#utils) + - [concatAll](#concatall) --- +# combinators + +## endo + +**Signature** + +```ts +export declare const endo:
(f: Endomorphism) => (M: Magma) => Magma +``` + +Added in v2.11.0 + +## filterFirst + +**Signature** + +```ts +export declare const filterFirst: (predicate: Predicate) => (M: Magma) => Magma +``` + +Added in v2.11.0 + +## filterSecond + +**Signature** + +```ts +export declare const filterSecond: (predicate: Predicate) => (M: Magma) => Magma +``` + +Added in v2.11.0 + +## reverse + +The dual of a `Magma`, obtained by swapping the arguments of `concat`. + +**Signature** + +```ts +export declare const reverse: (M: Magma) => Magma +``` + +**Example** + +```ts +import { reverse, concatAll } from 'fp-ts/Magma' +import * as N from 'fp-ts/number' + +const subAll = concatAll(reverse(N.MagmaSub))(0) + +assert.deepStrictEqual(subAll([1, 2, 3]), 2) +``` + +Added in v2.11.0 + # type classes ## Magma (interface) @@ -34,3 +96,30 @@ export interface Magma { ``` Added in v2.0.0 + +# utils + +## concatAll + +Given a sequence of `as`, concat them and return the total. + +If `as` is empty, return the provided `startWith` value. + +**Signature** + +```ts +export declare const concatAll: (M: Magma) => (startWith: A) => (as: readonly A[]) => A +``` + +**Example** + +```ts +import { concatAll } from 'fp-ts/Magma' +import * as N from 'fp-ts/number' + +const subAll = concatAll(N.MagmaSub)(0) + +assert.deepStrictEqual(subAll([1, 2, 3]), -6) +``` + +Added in v2.11.0 diff --git a/docs/modules/Map.ts.md b/docs/modules/Map.ts.md index 1a3c43fa3..03af530f9 100644 --- a/docs/modules/Map.ts.md +++ b/docs/modules/Map.ts.md @@ -1,6 +1,6 @@ --- title: Map.ts -nav_order: 54 +nav_order: 58 parent: Modules --- @@ -41,17 +41,26 @@ Added in v2.0.0 - [Functor](#functor-1) - [URI](#uri) - [URI (type alias)](#uri-type-alias) + - [getDifferenceMagma](#getdifferencemagma) - [getEq](#geteq) - [getFilterableWithIndex](#getfilterablewithindex) + - [getFoldable](#getfoldable) - [getFoldableWithIndex](#getfoldablewithindex) + - [getIntersectionSemigroup](#getintersectionsemigroup) - [getMonoid](#getmonoid) - [getShow](#getshow) - [getTraversableWithIndex](#gettraversablewithindex) + - [getUnionMonoid](#getunionmonoid) + - [getUnionSemigroup](#getunionsemigroup) - [getWitherable](#getwitherable) - [~~map\_~~](#map_) - [utils](#utils) - [collect](#collect) + - [difference](#difference) - [elem](#elem) + - [foldMap](#foldmap) + - [foldMapWithIndex](#foldmapwithindex) + - [intersection](#intersection) - [isEmpty](#isempty) - [isSubmap](#issubmap) - [keys](#keys) @@ -60,10 +69,15 @@ Added in v2.0.0 - [member](#member) - [modifyAt](#modifyat) - [pop](#pop) + - [reduce](#reduce) + - [reduceRight](#reduceright) + - [reduceRightWithIndex](#reducerightwithindex) + - [reduceWithIndex](#reducewithindex) - [singleton](#singleton) - [size](#size) - [toArray](#toarray) - [toUnfoldable](#tounfoldable) + - [union](#union) - [updateAt](#updateat) - [values](#values) - [~~empty~~](#empty) @@ -101,6 +115,7 @@ Added in v2.0.0 ```ts export declare const filter: { (refinement: Refinement): (fa: Map) => Map + (predicate: Predicate): (fb: Map) => Map (predicate: Predicate): (fa: Map) => Map } ``` @@ -124,6 +139,7 @@ Added in v2.0.0 ```ts export declare const partition: { (refinement: Refinement): (fa: Map) => Separated, Map> + (predicate: Predicate): (fb: Map) => Separated, Map> (predicate: Predicate): (fa: Map) => Separated, Map> } ``` @@ -198,7 +214,9 @@ Added in v2.10.0 **Signature** ```ts -export declare const filterWithIndex: (p: (k: K, a: A) => boolean) => (m: Map) => Map +export declare function filterWithIndex(p: (k: K, a: A) => a is B): (m: Map) => Map +export declare function filterWithIndex(p: (k: K, a: A) => boolean): (m: Map) => Map +export declare function filterWithIndex(p: (k: K, a: A) => boolean): (m: Map) => Map ``` Added in v2.10.0 @@ -232,9 +250,15 @@ Added in v2.10.0 **Signature** ```ts -export declare const partitionWithIndex: ( - p: (k: K, a: A) => boolean -) => (fa: Map) => Separated, Map> +export declare function partitionWithIndex( + predicateWithIndex: (k: K, a: A) => a is B +): (fa: Map) => Separated, Map> +export declare function partitionWithIndex( + predicateWithIndex: (k: K, a: A) => boolean +): (fb: Map) => Separated, Map> +export declare function partitionWithIndex( + predicateWithIndex: (k: K, a: A) => boolean +): (fa: Map) => Separated, Map> ``` Added in v2.10.0 @@ -345,6 +369,16 @@ export type URI = typeof URI Added in v2.0.0 +## getDifferenceMagma + +**Signature** + +```ts +export declare const getDifferenceMagma: (E: Eq) => () => Magma> +``` + +Added in v2.11.0 + ## getEq **Signature** @@ -365,6 +399,16 @@ export declare function getFilterableWithIndex(): FilterableWithIndex Added in v2.0.0 +## getFoldable + +**Signature** + +```ts +export declare const getFoldable: (O: Ord) => Foldable2C<'Map', K> +``` + +Added in v2.11.0 + ## getFoldableWithIndex **Signature** @@ -375,6 +419,16 @@ export declare const getFoldableWithIndex: (O: Ord) => FoldableWithIndex2C Added in v2.10.0 +## getIntersectionSemigroup + +**Signature** + +```ts +export declare const getIntersectionSemigroup: (E: Eq, S: Semigroup) => Semigroup> +``` + +Added in v2.11.0 + ## getMonoid Gets `Monoid` instance for Maps given `Semigroup` instance for their values @@ -407,6 +461,26 @@ export declare const getTraversableWithIndex: (O: Ord) => TraversableWithI Added in v2.10.0 +## getUnionMonoid + +**Signature** + +```ts +export declare const getUnionMonoid: (E: Eq, S: Semigroup) => Monoid> +``` + +Added in v2.11.0 + +## getUnionSemigroup + +**Signature** + +```ts +export declare const getUnionSemigroup: (E: Eq, S: Semigroup) => Semigroup> +``` + +Added in v2.11.0 + ## getWitherable **Signature** @@ -441,6 +515,16 @@ export declare function collect(O: Ord): (f: (k: K, a: A) => B) => ( Added in v2.0.0 +## difference + +**Signature** + +```ts +export declare const difference: (E: Eq) => (_second: Map) => (first: Map) => Map +``` + +Added in v2.11.0 + ## elem Test whether or not a value is a member of a map @@ -453,6 +537,41 @@ export declare const elem: (E: Eq) => { (a: A): (m: Map) => boole Added in v2.0.0 +## foldMap + +**Signature** + +```ts +export declare const foldMap: (O: Ord) => (M: Monoid) => (f: (a: A) => M) => (m: Map) => M +``` + +Added in v2.11.0 + +## foldMapWithIndex + +**Signature** + +```ts +export declare const foldMapWithIndex: ( + O: Ord +) => (M: Monoid) => (f: (k: K, a: A) => M) => (m: Map) => M +``` + +Added in v2.11.0 + +## intersection + +**Signature** + +```ts +export declare const intersection: ( + E: Eq, + M: Magma +) => (second: Map) => (first: Map) => Map +``` + +Added in v2.11.0 + ## isEmpty Test whether or not a map is empty @@ -460,7 +579,7 @@ Test whether or not a map is empty **Signature** ```ts -export declare const isEmpty: (d: Map) => boolean +export declare const isEmpty: (m: Map) => boolean ``` Added in v2.0.0 @@ -558,6 +677,48 @@ export declare function pop(E: Eq): (k: K) => (m: Map) => Option< Added in v2.0.0 +## reduce + +**Signature** + +```ts +export declare const reduce: (O: Ord) => (b: B, f: (b: B, a: A) => B) => (m: Map) => B +``` + +Added in v2.11.0 + +## reduceRight + +**Signature** + +```ts +export declare const reduceRight: (O: Ord) => (b: B, f: (a: A, b: B) => B) => (m: Map) => B +``` + +Added in v2.11.0 + +## reduceRightWithIndex + +**Signature** + +```ts +export declare const reduceRightWithIndex: ( + O: Ord +) => (b: B, f: (k: K, a: A, b: B) => B) => (m: Map) => B +``` + +Added in v2.11.0 + +## reduceWithIndex + +**Signature** + +```ts +export declare const reduceWithIndex: (O: Ord) => (b: B, f: (k: K, b: B, a: A) => B) => (m: Map) => B +``` + +Added in v2.11.0 + ## singleton Create a map with one key/value pair @@ -577,7 +738,7 @@ Calculate the number of key/value pairs in a map **Signature** ```ts -export declare const size: (d: Map) => number +export declare const size: (m: Map) => number ``` Added in v2.0.0 @@ -610,6 +771,16 @@ export declare function toUnfoldable(ord: Ord, U: Unfoldable): (d Added in v2.0.0 +## union + +**Signature** + +```ts +export declare const union: (E: Eq, M: Magma) => (second: Map) => (first: Map) => Map +``` + +Added in v2.11.0 + ## updateAt **Signature** diff --git a/docs/modules/MeetSemilattice.ts.md b/docs/modules/MeetSemilattice.ts.md index 2468e2070..e100614df 100644 --- a/docs/modules/MeetSemilattice.ts.md +++ b/docs/modules/MeetSemilattice.ts.md @@ -1,6 +1,6 @@ --- title: MeetSemilattice.ts -nav_order: 55 +nav_order: 59 parent: Modules --- diff --git a/docs/modules/Monad.ts.md b/docs/modules/Monad.ts.md index a3ad48c0b..8981f3fd8 100644 --- a/docs/modules/Monad.ts.md +++ b/docs/modules/Monad.ts.md @@ -1,6 +1,6 @@ --- title: Monad.ts -nav_order: 56 +nav_order: 60 parent: Modules --- diff --git a/docs/modules/MonadIO.ts.md b/docs/modules/MonadIO.ts.md index 5e82607d5..111cb30cc 100644 --- a/docs/modules/MonadIO.ts.md +++ b/docs/modules/MonadIO.ts.md @@ -1,6 +1,6 @@ --- title: MonadIO.ts -nav_order: 57 +nav_order: 61 parent: Modules --- diff --git a/docs/modules/MonadTask.ts.md b/docs/modules/MonadTask.ts.md index d23b022a0..14cb07bfc 100644 --- a/docs/modules/MonadTask.ts.md +++ b/docs/modules/MonadTask.ts.md @@ -1,6 +1,6 @@ --- title: MonadTask.ts -nav_order: 58 +nav_order: 62 parent: Modules --- diff --git a/docs/modules/MonadThrow.ts.md b/docs/modules/MonadThrow.ts.md index 8b6afa0ae..f0cd5aee4 100644 --- a/docs/modules/MonadThrow.ts.md +++ b/docs/modules/MonadThrow.ts.md @@ -1,6 +1,6 @@ --- title: MonadThrow.ts -nav_order: 59 +nav_order: 63 parent: Modules --- diff --git a/docs/modules/Monoid.ts.md b/docs/modules/Monoid.ts.md index 0d4529fed..d73c07e41 100644 --- a/docs/modules/Monoid.ts.md +++ b/docs/modules/Monoid.ts.md @@ -1,6 +1,6 @@ --- title: Monoid.ts -nav_order: 60 +nav_order: 64 parent: Modules --- @@ -56,7 +56,6 @@ Added in v2.0.0 - [~~getJoinMonoid~~](#getjoinmonoid) - [~~getMeetMonoid~~](#getmeetmonoid) - [instances](#instances) - - [monoidVoid](#monoidvoid) - [~~getEndomorphismMonoid~~](#getendomorphismmonoid) - [~~getFunctionMonoid~~](#getfunctionmonoid) - [~~monoidAll~~](#monoidall) @@ -64,6 +63,7 @@ Added in v2.0.0 - [~~monoidProduct~~](#monoidproduct) - [~~monoidString~~](#monoidstring) - [~~monoidSum~~](#monoidsum) + - [~~monoidVoid~~](#monoidvoid) - [type classes](#type-classes) - [Monoid (interface)](#monoid-interface) - [utils](#utils) @@ -273,16 +273,6 @@ Added in v2.0.0 # instances -## monoidVoid - -**Signature** - -```ts -export declare const monoidVoid: Monoid -``` - -Added in v2.0.0 - ## ~~getEndomorphismMonoid~~ Use [`getEndomorphismMonoid`](./function.ts.html#getendomorphismmonoid) instead. @@ -369,6 +359,18 @@ export declare const monoidSum: Monoid Added in v2.0.0 +## ~~monoidVoid~~ + +Use [`Monoid`](./void.ts.html#monoid) instead. + +**Signature** + +```ts +export declare const monoidVoid: Monoid +``` + +Added in v2.0.0 + # type classes ## Monoid (interface) diff --git a/docs/modules/NaturalTransformation.ts.md b/docs/modules/NaturalTransformation.ts.md new file mode 100644 index 000000000..5494652e9 --- /dev/null +++ b/docs/modules/NaturalTransformation.ts.md @@ -0,0 +1,287 @@ +--- +title: NaturalTransformation.ts +nav_order: 65 +parent: Modules +--- + +## NaturalTransformation overview + +A type for natural transformations. + +A natural transformation is a mapping between type constructors of kind `* -> *` where the mapping +operation has no ability to manipulate the inner values. + +The definition of a natural transformation in category theory states that `F` and `G` should be functors, +but the `Functor` constraint is not enforced here; that the types are of kind `* -> *` is enough for our purposes. + +Added in v2.11.0 + +--- + +

Table of contents

+ +- [utils](#utils) + - [NaturalTransformation (interface)](#naturaltransformation-interface) + - [NaturalTransformation11 (interface)](#naturaltransformation11-interface) + - [NaturalTransformation12 (interface)](#naturaltransformation12-interface) + - [NaturalTransformation12C (interface)](#naturaltransformation12c-interface) + - [NaturalTransformation13 (interface)](#naturaltransformation13-interface) + - [NaturalTransformation13C (interface)](#naturaltransformation13c-interface) + - [NaturalTransformation14 (interface)](#naturaltransformation14-interface) + - [NaturalTransformation14C (interface)](#naturaltransformation14c-interface) + - [NaturalTransformation21 (interface)](#naturaltransformation21-interface) + - [NaturalTransformation22 (interface)](#naturaltransformation22-interface) + - [NaturalTransformation22C (interface)](#naturaltransformation22c-interface) + - [NaturalTransformation23 (interface)](#naturaltransformation23-interface) + - [NaturalTransformation23C (interface)](#naturaltransformation23c-interface) + - [NaturalTransformation23R (interface)](#naturaltransformation23r-interface) + - [NaturalTransformation23RC (interface)](#naturaltransformation23rc-interface) + - [NaturalTransformation24 (interface)](#naturaltransformation24-interface) + - [NaturalTransformation24R (interface)](#naturaltransformation24r-interface) + - [NaturalTransformation24S (interface)](#naturaltransformation24s-interface) + - [NaturalTransformation33 (interface)](#naturaltransformation33-interface) + - [NaturalTransformation34 (interface)](#naturaltransformation34-interface) + +--- + +# utils + +## NaturalTransformation (interface) + +**Signature** + +```ts +export interface NaturalTransformation { +
(fa: HKT): HKT +} +``` + +Added in v2.11.0 + +## NaturalTransformation11 (interface) + +**Signature** + +```ts +export interface NaturalTransformation11 { + (fa: Kind): Kind +} +``` + +Added in v2.11.0 + +## NaturalTransformation12 (interface) + +**Signature** + +```ts +export interface NaturalTransformation12 { + (fa: Kind): Kind2 +} +``` + +Added in v2.11.0 + +## NaturalTransformation12C (interface) + +**Signature** + +```ts +export interface NaturalTransformation12C { + (fa: Kind): Kind2 +} +``` + +Added in v2.11.0 + +## NaturalTransformation13 (interface) + +**Signature** + +```ts +export interface NaturalTransformation13 { + (fa: Kind): Kind3 +} +``` + +Added in v2.11.0 + +## NaturalTransformation13C (interface) + +**Signature** + +```ts +export interface NaturalTransformation13C { + (fa: Kind): Kind3 +} +``` + +Added in v2.11.0 + +## NaturalTransformation14 (interface) + +**Signature** + +```ts +export interface NaturalTransformation14 { + (fa: Kind): Kind4 +} +``` + +Added in v2.11.0 + +## NaturalTransformation14C (interface) + +**Signature** + +```ts +export interface NaturalTransformation14C { + (fa: Kind): Kind4 +} +``` + +Added in v2.11.0 + +## NaturalTransformation21 (interface) + +**Signature** + +```ts +export interface NaturalTransformation21 { + (fa: Kind2): Kind +} +``` + +Added in v2.11.0 + +## NaturalTransformation22 (interface) + +**Signature** + +```ts +export interface NaturalTransformation22 { + (fa: Kind2): Kind2 +} +``` + +Added in v2.11.0 + +## NaturalTransformation22C (interface) + +**Signature** + +```ts +export interface NaturalTransformation22C { + (fa: Kind2): Kind2 +} +``` + +Added in v2.11.0 + +## NaturalTransformation23 (interface) + +**Signature** + +```ts +export interface NaturalTransformation23 { + (fa: Kind2): Kind3 +} +``` + +Added in v2.11.0 + +## NaturalTransformation23C (interface) + +**Signature** + +```ts +export interface NaturalTransformation23C { + (fa: Kind2): Kind3 +} +``` + +Added in v2.11.0 + +## NaturalTransformation23R (interface) + +**Signature** + +```ts +export interface NaturalTransformation23R { + (fa: Kind2): Kind3 +} +``` + +Added in v2.11.0 + +## NaturalTransformation23RC (interface) + +**Signature** + +```ts +export interface NaturalTransformation23RC { + (fa: Kind2): Kind3 +} +``` + +Added in v2.11.0 + +## NaturalTransformation24 (interface) + +**Signature** + +```ts +export interface NaturalTransformation24 { + (fa: Kind2): Kind4 +} +``` + +Added in v2.11.0 + +## NaturalTransformation24R (interface) + +**Signature** + +```ts +export interface NaturalTransformation24R { + (fa: Kind2): Kind4 +} +``` + +Added in v2.11.0 + +## NaturalTransformation24S (interface) + +**Signature** + +```ts +export interface NaturalTransformation24S { + (fa: Kind2): Kind4 +} +``` + +Added in v2.11.0 + +## NaturalTransformation33 (interface) + +**Signature** + +```ts +export interface NaturalTransformation33 { + (fa: Kind3): Kind3 +} +``` + +Added in v2.11.0 + +## NaturalTransformation34 (interface) + +**Signature** + +```ts +export interface NaturalTransformation34 { + (fa: Kind3): Kind4 +} +``` + +Added in v2.11.0 diff --git a/docs/modules/NonEmptyArray.ts.md b/docs/modules/NonEmptyArray.ts.md index e43eb2589..2a9e3116f 100644 --- a/docs/modules/NonEmptyArray.ts.md +++ b/docs/modules/NonEmptyArray.ts.md @@ -1,6 +1,6 @@ --- title: NonEmptyArray.ts -nav_order: 61 +nav_order: 66 parent: Modules --- @@ -52,35 +52,48 @@ Added in v2.0.0 - [chop](#chop) - [chunksOf](#chunksof) - [concat](#concat) + - [concatW](#concatw) - [copy](#copy) - [duplicate](#duplicate) - [flap](#flap) - [flatten](#flatten) - [foldMap](#foldmap) - [foldMapWithIndex](#foldmapwithindex) + - [getUnionSemigroup](#getunionsemigroup) - [group](#group) - [groupBy](#groupby) - - [groupSort](#groupsort) - [insertAt](#insertat) - [intersperse](#intersperse) - [modifyAt](#modifyat) - [prependAll](#prependall) - [reverse](#reverse) + - [rotate](#rotate) - [sort](#sort) + - [sortBy](#sortby) - [splitAt](#splitat) + - [union](#union) + - [uniq](#uniq) - [unzip](#unzip) - [updateAt](#updateat) + - [updateHead](#updatehead) + - [updateLast](#updatelast) - [zip](#zip) - [zipWith](#zipwith) - [~~filterWithIndex~~](#filterwithindex) - [~~filter~~](#filter) + - [~~groupSort~~](#groupsort) - [~~prependToAll~~](#prependtoall) - [constructors](#constructors) - [fromArray](#fromarray) - [fromReadonlyNonEmptyArray](#fromreadonlynonemptyarray) + - [makeBy](#makeby) + - [range](#range) + - [replicate](#replicate) - [~~cons~~](#cons) - [~~snoc~~](#snoc) - [destructors](#destructors) + - [matchLeft](#matchleft) + - [matchRight](#matchright) - [unappend](#unappend) - [unprepend](#unprepend) - [~~uncons~~](#uncons) @@ -119,6 +132,8 @@ Added in v2.0.0 - [last](#last) - [max](#max) - [min](#min) + - [modifyHead](#modifyhead) + - [modifyLast](#modifylast) - [sequence](#sequence) - [tail](#tail) - [traverse](#traverse) @@ -359,12 +374,25 @@ Added in v2.10.0 **Signature** ```ts +export declare function concat(second: NonEmptyArray): (first: Array) => NonEmptyArray +export declare function concat(second: Array): (first: NonEmptyArray) => NonEmptyArray export declare function concat(first: Array, second: NonEmptyArray): NonEmptyArray export declare function concat(first: NonEmptyArray, second: Array): NonEmptyArray ``` Added in v2.2.0 +## concatW + +**Signature** + +```ts +export declare function concatW(second: NonEmptyArray): (first: Array) => NonEmptyArray +export declare function concatW(second: Array): (first: NonEmptyArray) => NonEmptyArray +``` + +Added in v2.11.0 + ## copy **Signature** @@ -433,6 +461,16 @@ export declare const foldMapWithIndex: ( Added in v2.0.0 +## getUnionSemigroup + +**Signature** + +```ts +export declare const getUnionSemigroup: (E: Eq) => Se.Semigroup> +``` + +Added in v2.11.0 + ## group Group equal, consecutive elements of an array into non empty arrays. @@ -483,38 +521,12 @@ assert.deepStrictEqual(groupBy((s: string) => String(s.length))(['a', 'b', 'ab'] Added in v2.0.0 -## groupSort - -Sort and then group the elements of an array into non empty arrays. - -**Signature** - -```ts -export declare function groupSort( - O: Ord -): { - (as: NonEmptyArray): NonEmptyArray> - (as: Array): Array> -} -``` - -**Example** - -```ts -import { groupSort } from 'fp-ts/NonEmptyArray' -import * as N from 'fp-ts/number' - -assert.deepStrictEqual(groupSort(N.Ord)([1, 2, 1, 1]), [[1, 1, 1], [2]]) -``` - -Added in v2.0.0 - ## insertAt **Signature** ```ts -export declare const insertAt: (i: number, a: A) => (as: A[]) => O.Option> +export declare const insertAt: (i: number, a: A) => (as: A[]) => Option> ``` Added in v2.0.0 @@ -544,7 +556,7 @@ Added in v2.9.0 **Signature** ```ts -export declare const modifyAt: (i: number, f: (a: A) => A) => (as: NonEmptyArray) => O.Option> +export declare const modifyAt: (i: number, f: (a: A) => A) => (as: NonEmptyArray) => Option> ``` Added in v2.0.0 @@ -579,6 +591,27 @@ export declare const reverse: (as: NonEmptyArray) => NonEmptyArray Added in v2.0.0 +## rotate + +Rotate a `NonEmptyArray` by `n` steps. + +**Signature** + +```ts +export declare const rotate: (n: number) => (as: NonEmptyArray) => NonEmptyArray +``` + +**Example** + +```ts +import { rotate } from 'fp-ts/NonEmptyArray' + +assert.deepStrictEqual(rotate(2)([1, 2, 3, 4, 5]), [4, 5, 1, 2, 3]) +assert.deepStrictEqual(rotate(-2)([1, 2, 3, 4, 5]), [3, 4, 5, 1, 2]) +``` + +Added in v2.11.0 + ## sort **Signature** @@ -589,6 +622,60 @@ export declare const sort: (O: Ord) => (as: NonEmptyArray) Added in v2.0.0 +## sortBy + +Sort the elements of a `NonEmptyArray` in increasing order, where elements are compared using first `ords[0]`, then `ords[1]`, +etc... + +**Signature** + +```ts +export declare const sortBy: (ords: Ord[]) => (as: NonEmptyArray) => NonEmptyArray +``` + +**Example** + +```ts +import * as NEA from 'fp-ts/NonEmptyArray' +import { contramap } from 'fp-ts/Ord' +import * as S from 'fp-ts/string' +import * as N from 'fp-ts/number' +import { pipe } from 'fp-ts/function' + +interface Person { + name: string + age: number +} + +const byName = pipe( + S.Ord, + contramap((p: Person) => p.name) +) + +const byAge = pipe( + N.Ord, + contramap((p: Person) => p.age) +) + +const sortByNameByAge = NEA.sortBy([byName, byAge]) + +const persons: NEA.NonEmptyArray = [ + { name: 'a', age: 1 }, + { name: 'b', age: 3 }, + { name: 'c', age: 2 }, + { name: 'b', age: 2 }, +] + +assert.deepStrictEqual(sortByNameByAge(persons), [ + { name: 'a', age: 1 }, + { name: 'b', age: 2 }, + { name: 'b', age: 3 }, + { name: 'c', age: 2 }, +]) +``` + +Added in v2.11.0 + ## splitAt Splits a `NonEmptyArray` into two pieces, the first piece has max `n` elements. @@ -601,6 +688,37 @@ export declare const splitAt: (n: number) => (as: NonEmptyArray) => [NonEm Added in v2.10.0 +## union + +**Signature** + +```ts +export declare const union: (E: Eq) => (second: NonEmptyArray) => (first: NonEmptyArray) => NonEmptyArray +``` + +Added in v2.11.0 + +## uniq + +Remove duplicates from a `NonEmptyArray`, keeping the first occurrence of an element. + +**Signature** + +```ts +export declare const uniq: (E: Eq) => (as: NonEmptyArray) => NonEmptyArray +``` + +**Example** + +```ts +import { uniq } from 'fp-ts/NonEmptyArray' +import * as N from 'fp-ts/number' + +assert.deepStrictEqual(uniq(N.Eq)([1, 2, 1]), [1, 2]) +``` + +Added in v2.11.0 + ## unzip **Signature** @@ -616,11 +734,35 @@ Added in v2.5.1 **Signature** ```ts -export declare const updateAt: (i: number, a: A) => (as: NonEmptyArray) => O.Option> +export declare const updateAt: (i: number, a: A) => (as: NonEmptyArray) => Option> ``` Added in v2.0.0 +## updateHead + +Change the head, creating a new `NonEmptyArray`. + +**Signature** + +```ts +export declare const updateHead: (a: A) => (as: NonEmptyArray) => NonEmptyArray +``` + +Added in v2.11.0 + +## updateLast + +Change the last element, creating a new `NonEmptyArray`. + +**Signature** + +```ts +export declare const updateLast: (a: A) => (as: NonEmptyArray) => NonEmptyArray +``` + +Added in v2.11.0 + ## zip **Signature** @@ -655,7 +797,7 @@ Use [`filterWithIndex`](./Array.ts.html#filterwithindex) instead. ```ts export declare const filterWithIndex: ( predicate: (i: number, a: A) => boolean -) => (as: NonEmptyArray) => O.Option> +) => (as: NonEmptyArray) => Option> ``` Added in v2.0.0 @@ -670,11 +812,31 @@ Use [`filter`](./Array.ts.html#filter) instead. export declare function filter( refinement: Refinement ): (as: NonEmptyArray) => Option> +export declare function filter( + predicate: Predicate +): (bs: NonEmptyArray) => Option> export declare function filter(predicate: Predicate): (as: NonEmptyArray) => Option> ``` Added in v2.0.0 +## ~~groupSort~~ + +This is just `sort` followed by `group`. + +**Signature** + +```ts +export declare function groupSort( + O: Ord +): { + (as: NonEmptyArray): NonEmptyArray> + (as: Array): Array> +} +``` + +Added in v2.0.0 + ## ~~prependToAll~~ Use [`prependAll`](#prependall) instead. @@ -696,7 +858,7 @@ Builds a `NonEmptyArray` from an `Array` returning `none` if `as` is an empty ar **Signature** ```ts -export declare const fromArray: (as: A[]) => O.Option> +export declare const fromArray: (as: A[]) => Option> ``` Added in v2.0.0 @@ -711,6 +873,73 @@ export declare const fromReadonlyNonEmptyArray: (as: RNEA.ReadonlyNonEmptyArr Added in v2.10.0 +## makeBy + +Return a `NonEmptyArray` of length `n` with element `i` initialized with `f(i)`. + +**Note**. `n` is normalized to a natural number. + +**Signature** + +```ts +export declare const makeBy: (f: (i: number) => A) => (n: number) => NonEmptyArray +``` + +**Example** + +```ts +import { makeBy } from 'fp-ts/NonEmptyArray' +import { pipe } from 'fp-ts/function' + +const double = (n: number): number => n * 2 +assert.deepStrictEqual(pipe(5, makeBy(double)), [0, 2, 4, 6, 8]) +``` + +Added in v2.11.0 + +## range + +Create a `NonEmptyArray` containing a range of integers, including both endpoints. + +**Signature** + +```ts +export declare const range: (start: number, end: number) => NonEmptyArray +``` + +**Example** + +```ts +import { range } from 'fp-ts/NonEmptyArray' + +assert.deepStrictEqual(range(1, 5), [1, 2, 3, 4, 5]) +``` + +Added in v2.11.0 + +## replicate + +Create a `NonEmptyArray` containing a value repeated the specified number of times. + +**Note**. `n` is normalized to a natural number. + +**Signature** + +```ts +export declare const replicate: (a: A) => (n: number) => RNEA.ReadonlyNonEmptyArray +``` + +**Example** + +```ts +import { replicate } from 'fp-ts/NonEmptyArray' +import { pipe } from 'fp-ts/function' + +assert.deepStrictEqual(pipe(3, replicate('a')), ['a', 'a', 'a']) +``` + +Added in v2.11.0 + ## ~~cons~~ Use [`prepend`](./Array.ts.html#prepend) instead. @@ -738,6 +967,30 @@ Added in v2.0.0 # destructors +## matchLeft + +Break an `Array` into its first element and remaining elements. + +**Signature** + +```ts +export declare const matchLeft: (f: (head: A, tail: A[]) => B) => (as: NonEmptyArray) => B +``` + +Added in v2.11.0 + +## matchRight + +Break an `Array` into its initial elements and the last element. + +**Signature** + +```ts +export declare const matchRight: (f: (init: A[], last: A) => B) => (as: NonEmptyArray) => B +``` + +Added in v2.11.0 + ## unappend Return the tuple of the `init` and the `last`. @@ -1158,6 +1411,30 @@ export declare const min: (ord: Ord) => (nea: NonEmptyArray) => A Added in v2.0.0 +## modifyHead + +Apply a function to the head, creating a new `NonEmptyArray`. + +**Signature** + +```ts +export declare const modifyHead: (f: Endomorphism) => (as: NonEmptyArray) => NonEmptyArray +``` + +Added in v2.11.0 + +## modifyLast + +Apply a function to the last element, creating a new `NonEmptyArray`. + +**Signature** + +```ts +export declare const modifyLast: (f: Endomorphism) => (as: NonEmptyArray) => NonEmptyArray +``` + +Added in v2.11.0 + ## sequence **Signature** diff --git a/docs/modules/Option.ts.md b/docs/modules/Option.ts.md index fdd744c29..65d51d150 100644 --- a/docs/modules/Option.ts.md +++ b/docs/modules/Option.ts.md @@ -1,6 +1,6 @@ --- title: Option.ts -nav_order: 63 +nav_order: 68 parent: Modules --- @@ -23,54 +23,21 @@ Added in v2.0.0

Table of contents

-- [Alt](#alt) - - [alt](#alt) - - [altW](#altw) -- [Alternative](#alternative) - - [zero](#zero) -- [Apply](#apply) - - [ap](#ap) -- [Compactable](#compactable) - - [compact](#compact) - - [separate](#separate) -- [Extend](#extend) - - [extend](#extend) -- [Filterable](#filterable) - - [filter](#filter) - - [filterMap](#filtermap) - - [partition](#partition) - - [partitionMap](#partitionmap) -- [Foldable](#foldable) - - [foldMap](#foldmap) - - [reduce](#reduce) - - [reduceRight](#reduceright) -- [Functor](#functor) - - [map](#map) -- [Monad](#monad) - - [chain](#chain) -- [MonadThrow](#monadthrow) - - [throwError](#throwerror) -- [Pointed](#pointed) - - [of](#of) -- [Traversable](#traversable) - - [sequence](#sequence) - - [traverse](#traverse) -- [Witherable](#witherable) - - [wilt](#wilt) - - [wither](#wither) - [combinators](#combinators) - [apFirst](#apfirst) - [apSecond](#apsecond) + - [chainEitherK](#chaineitherk) - [chainFirst](#chainfirst) - [duplicate](#duplicate) - [flap](#flap) - [flatten](#flatten) + - [fromEitherK](#fromeitherk) - [~~mapNullable~~](#mapnullable) - [constructors](#constructors) - - [fromEither](#fromeither) - [fromPredicate](#frompredicate) - [getLeft](#getleft) - [getRight](#getright) + - [guard](#guard) - [none](#none) - [some](#some) - [destructors](#destructors) @@ -80,35 +47,57 @@ Added in v2.0.0 - [getOrElseW](#getorelsew) - [match](#match) - [matchW](#matchw) -- [guards](#guards) - - [isNone](#isnone) - - [isSome](#issome) +- [instance operations](#instance-operations) + - [alt](#alt) + - [altW](#altw) + - [ap](#ap) + - [chain](#chain) + - [compact](#compact) + - [extend](#extend) + - [filter](#filter) + - [filterMap](#filtermap) + - [foldMap](#foldmap) + - [map](#map) + - [of](#of) + - [partition](#partition) + - [partitionMap](#partitionmap) + - [reduce](#reduce) + - [reduceRight](#reduceright) + - [separate](#separate) + - [sequence](#sequence) + - [throwError](#throwerror) + - [traverse](#traverse) + - [wilt](#wilt) + - [wither](#wither) + - [zero](#zero) - [instances](#instances) - - [Alt](#alt-1) - - [Alternative](#alternative-1) + - [Alt](#alt) + - [Alternative](#alternative) - [Applicative](#applicative) - - [Apply](#apply-1) + - [Apply](#apply) - [Chain](#chain) - - [Compactable](#compactable-1) - - [Extend](#extend-1) - - [Filterable](#filterable-1) - - [Foldable](#foldable-1) - - [Functor](#functor-1) - - [Monad](#monad-1) - - [MonadThrow](#monadthrow-1) - - [Pointed](#pointed-1) - - [Traversable](#traversable-1) + - [Compactable](#compactable) + - [Extend](#extend) + - [Filterable](#filterable) + - [Foldable](#foldable) + - [FromEither](#fromeither) + - [Functor](#functor) + - [Monad](#monad) + - [MonadThrow](#monadthrow) + - [Pointed](#pointed) + - [Traversable](#traversable) - [URI](#uri) - [URI (type alias)](#uri-type-alias) - - [Witherable](#witherable-1) + - [Witherable](#witherable) + - [Zero](#zero) - [getEq](#geteq) - - [getFirstMonoid](#getfirstmonoid) - - [getLastMonoid](#getlastmonoid) - [getMonoid](#getmonoid) - [getOrd](#getord) - [getShow](#getshow) - [~~getApplyMonoid~~](#getapplymonoid) - [~~getApplySemigroup~~](#getapplysemigroup) + - [~~getFirstMonoid~~](#getfirstmonoid) + - [~~getLastMonoid~~](#getlastmonoid) - [~~option~~](#option) - [interop](#interop) - [chainNullableK](#chainnullablek) @@ -122,339 +111,67 @@ Added in v2.0.0 - [None (interface)](#none-interface) - [Option (type alias)](#option-type-alias) - [Some (interface)](#some-interface) +- [natural transformations](#natural-transformations) + - [fromEither](#fromeither) +- [refinements](#refinements) + - [isNone](#isnone) + - [isSome](#issome) - [utils](#utils) + - [ApT](#apt) - [Do](#do) - [apS](#aps) - [bind](#bind) - [bindTo](#bindto) - [elem](#elem) - [exists](#exists) - - [getRefinement](#getrefinement) - [sequenceArray](#sequencearray) - [traverseArray](#traversearray) - [traverseArrayWithIndex](#traversearraywithindex) + - [traverseReadonlyArrayWithIndex](#traversereadonlyarraywithindex) + - [traverseReadonlyNonEmptyArrayWithIndex](#traversereadonlynonemptyarraywithindex) + - [~~getRefinement~~](#getrefinement) --- -# Alt - -## alt - -Identifies an associative operation on a type constructor. It is similar to `Semigroup`, except that it applies to -types of kind `* -> *`. - -In case of `Option` returns the left-most non-`None` value. - -**Signature** - -```ts -export declare const alt:
(that: Lazy>) => (fa: Option) => Option -``` - -**Example** - -```ts -import * as O from 'fp-ts/Option' -import { pipe } from 'fp-ts/function' - -assert.deepStrictEqual( - pipe( - O.some('a'), - O.alt(() => O.some('b')) - ), - O.some('a') -) -assert.deepStrictEqual( - pipe( - O.none, - O.alt(() => O.some('b')) - ), - O.some('b') -) -``` - -Added in v2.0.0 - -## altW - -Less strict version of [`alt`](#alt). - -**Signature** - -```ts -export declare const altW: (that: Lazy>) => (fa: Option) => Option -``` - -Added in v2.9.0 - -# Alternative - -## zero - -**Signature** - -```ts -export declare const zero: () => Option -``` - -Added in v2.7.0 - -# Apply - -## ap - -Apply a function to an argument under a type constructor. - -**Signature** - -```ts -export declare const ap: (fa: Option) => (fab: Option<(a: A) => B>) => Option -``` - -Added in v2.0.0 - -# Compactable - -## compact - -**Signature** - -```ts -export declare const compact: (fa: Option>) => Option -``` - -Added in v2.0.0 - -## separate - -**Signature** - -```ts -export declare const separate: (ma: Option>) => Separated, Option> -``` - -Added in v2.0.0 - -# Extend - -## extend - -**Signature** - -```ts -export declare const extend: (f: (wa: Option) => B) => (wa: Option) => Option -``` - -Added in v2.0.0 - -# Filterable - -## filter - -**Signature** - -```ts -export declare const filter: { - (refinement: Refinement): (fa: Option) => Option - (predicate: Predicate): (fa: Option) => Option -} -``` - -Added in v2.0.0 - -## filterMap - -**Signature** - -```ts -export declare const filterMap: (f: (a: A) => Option) => (fa: Option) => Option -``` - -Added in v2.0.0 - -## partition - -**Signature** - -```ts -export declare const partition: { - (refinement: Refinement): (fa: Option) => Separated, Option> - (predicate: Predicate): (fa: Option) => Separated, Option> -} -``` - -Added in v2.0.0 - -## partitionMap - -**Signature** - -```ts -export declare const partitionMap: ( - f: (a: A) => Either -) => (fa: Option) => Separated, Option> -``` - -Added in v2.0.0 - -# Foldable - -## foldMap - -**Signature** - -```ts -export declare const foldMap: (M: Monoid) => (f: (a: A) => M) => (fa: Option) => M -``` - -Added in v2.0.0 - -## reduce - -**Signature** - -```ts -export declare const reduce: (b: B, f: (b: B, a: A) => B) => (fa: Option) => B -``` - -Added in v2.0.0 - -## reduceRight - -**Signature** - -```ts -export declare const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: Option) => B -``` - -Added in v2.0.0 - -# Functor - -## map - -`map` can be used to turn functions `(a: A) => B` into functions `(fa: F) => F` whose argument and return types -use the type constructor `F` to represent some computational context. - -**Signature** - -```ts -export declare const map: (f: (a: A) => B) => (fa: Option) => Option -``` - -Added in v2.0.0 +# combinators -# Monad +## apFirst -## chain +Combine two effectful actions, keeping only the result of the first. -Composes computations in sequence, using the return value of one computation to determine the next computation. +Derivable from `Apply`. **Signature** ```ts -export declare const chain: (f: (a: A) => Option) => (ma: Option) => Option +export declare const apFirst: (second: Option) => (first: Option) => Option ``` Added in v2.0.0 -# MonadThrow - -## throwError - -**Signature** - -```ts -export declare const throwError: (e: E) => Option -``` - -Added in v2.7.0 - -# Pointed - -## of - -**Signature** - -```ts -export declare const of: (a: A) => Option -``` - -Added in v2.7.0 - -# Traversable - -## sequence - -**Signature** - -```ts -export declare const sequence: Sequence1<'Option'> -``` - -Added in v2.6.3 - -## traverse - -**Signature** - -```ts -export declare const traverse: PipeableTraverse1<'Option'> -``` - -Added in v2.6.3 - -# Witherable - -## wilt - -**Signature** - -```ts -export declare const wilt: PipeableWilt1<'Option'> -``` - -Added in v2.6.5 - -## wither - -**Signature** - -```ts -export declare const wither: PipeableWither1<'Option'> -``` - -Added in v2.6.5 - -# combinators - -## apFirst +## apSecond -Combine two effectful actions, keeping only the result of the first. +Combine two effectful actions, keeping only the result of the second. Derivable from `Apply`. **Signature** ```ts -export declare const apFirst: (second: Option) => (first: Option) => Option +export declare const apSecond: (second: Option) => (first: Option) => Option ``` -Added in v2.0.0 - -## apSecond - -Combine two effectful actions, keeping only the result of the second. +Added in v2.0.0 -Derivable from `Apply`. +## chainEitherK **Signature** ```ts -export declare const apSecond: (second: Option) => (first: Option) => Option +export declare const chainEitherK: (f: (a: A) => Either) => (ma: Option) => Option ``` -Added in v2.0.0 +Added in v2.11.0 ## chainFirst @@ -507,34 +224,30 @@ export declare const flatten: (mma: Option>) => Option Added in v2.0.0 -## ~~mapNullable~~ - -Use [`chainNullableK`](#chainnullablek) instead. +## fromEitherK **Signature** ```ts -export declare const mapNullable: (f: (a: A) => B | null | undefined) => (ma: Option) => Option +export declare const fromEitherK: (f: (...a: A) => Either) => (...a: A) => Option ``` -Added in v2.0.0 - -# constructors - -## fromEither +Added in v2.11.0 -Transforms an `Either` to an `Option` discarding the error. +## ~~mapNullable~~ -Alias of [getRight](#getright) +Use [`chainNullableK`](#chainnullablek) instead. **Signature** ```ts -export declare const fromEither: (ma: Either) => Option +export declare const mapNullable: (f: (a: A) => B | null | undefined) => (ma: Option) => Option ``` Added in v2.0.0 +# constructors + ## fromPredicate Returns a _smart constructor_ based on the given predicate. @@ -543,6 +256,7 @@ Returns a _smart constructor_ based on the given predicate. ```ts export declare function fromPredicate(refinement: Refinement): (a: A) => Option +export declare function fromPredicate(predicate: Predicate): (b: B) => Option export declare function fromPredicate(predicate: Predicate): (a: A) => Option ``` @@ -566,7 +280,7 @@ Returns the `Left` value of an `Either` if possible. **Signature** ```ts -export declare function getLeft(ma: Either): Option +export declare const getLeft: (ma: Either) => Option ``` **Example** @@ -588,7 +302,7 @@ Returns the `Right` value of an `Either` if possible. **Signature** ```ts -export declare function getRight(ma: Either): Option +export declare const getRight: (ma: Either) => Option ``` **Example** @@ -603,6 +317,16 @@ assert.deepStrictEqual(getRight(left('a')), none) Added in v2.0.0 +## guard + +**Signature** + +```ts +export declare const guard: (b: boolean) => Option +``` + +Added in v2.11.0 + ## none `None` doesn't have a constructor, instead you can use it directly as a value. Represents a missing value. @@ -753,49 +477,268 @@ export declare const matchW: (onNone: Lazy, onSome: (a: A) => C) => Added in v2.10.0 -# guards +# instance operations -## isNone +## alt -Returns `true` if the option is `None`, `false` otherwise. +Identifies an associative operation on a type constructor. It is similar to `Semigroup`, except that it applies to +types of kind `* -> *`. + +In case of `Option` returns the left-most non-`None` value. **Signature** ```ts -export declare const isNone: (fa: Option) => fa is None +export declare const alt: (that: Lazy>) => (fa: Option) => Option ``` **Example** ```ts -import { some, none, isNone } from 'fp-ts/Option' +import * as O from 'fp-ts/Option' +import { pipe } from 'fp-ts/function' -assert.strictEqual(isNone(some(1)), false) -assert.strictEqual(isNone(none), true) +assert.deepStrictEqual( + pipe( + O.some('a'), + O.alt(() => O.some('b')) + ), + O.some('a') +) +assert.deepStrictEqual( + pipe( + O.none, + O.alt(() => O.some('b')) + ), + O.some('b') +) ``` Added in v2.0.0 -## isSome +## altW + +Less strict version of [`alt`](#alt). + +**Signature** + +```ts +export declare const altW: (that: Lazy>) => (fa: Option) => Option +``` + +Added in v2.9.0 + +## ap + +**Signature** + +```ts +export declare const ap: (fa: Option) => (fab: Option<(a: A) => B>) => Option +``` + +Added in v2.0.0 + +## chain + +Composes computations in sequence, using the return value of one computation to determine the next computation. + +**Signature** + +```ts +export declare const chain: (f: (a: A) => Option) => (ma: Option) => Option +``` + +Added in v2.0.0 + +## compact + +**Signature** + +```ts +export declare const compact: (fa: Option>) => Option +``` + +Added in v2.0.0 + +## extend + +**Signature** + +```ts +export declare const extend: (f: (wa: Option) => B) => (wa: Option) => Option +``` + +Added in v2.0.0 + +## filter + +**Signature** + +```ts +export declare const filter: { + (refinement: Refinement): (fa: Option) => Option + (predicate: Predicate): (fb: Option) => Option + (predicate: Predicate): (fa: Option) => Option +} +``` + +Added in v2.0.0 + +## filterMap + +**Signature** + +```ts +export declare const filterMap: (f: (a: A) => Option) => (fa: Option) => Option +``` + +Added in v2.0.0 + +## foldMap + +**Signature** + +```ts +export declare const foldMap: (M: Monoid) => (f: (a: A) => M) => (fa: Option) => M +``` + +Added in v2.0.0 + +## map + +**Signature** + +```ts +export declare const map: (f: (a: A) => B) => (fa: Option) => Option +``` + +Added in v2.0.0 + +## of + +**Signature** + +```ts +export declare const of: (a: A) => Option +``` + +Added in v2.7.0 + +## partition + +**Signature** + +```ts +export declare const partition: { + (refinement: Refinement): (fa: Option) => Separated, Option> + (predicate: Predicate): (fb: Option) => Separated, Option> + (predicate: Predicate): (fa: Option) => Separated, Option> +} +``` + +Added in v2.0.0 + +## partitionMap + +**Signature** + +```ts +export declare const partitionMap: ( + f: (a: A) => Either +) => (fa: Option) => Separated, Option> +``` + +Added in v2.0.0 + +## reduce + +**Signature** + +```ts +export declare const reduce: (b: B, f: (b: B, a: A) => B) => (fa: Option) => B +``` + +Added in v2.0.0 + +## reduceRight + +**Signature** + +```ts +export declare const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: Option) => B +``` + +Added in v2.0.0 + +## separate + +**Signature** + +```ts +export declare const separate: (ma: Option>) => Separated, Option> +``` + +Added in v2.0.0 + +## sequence + +**Signature** + +```ts +export declare const sequence: Sequence1<'Option'> +``` + +Added in v2.6.3 + +## throwError + +**Signature** + +```ts +export declare const throwError: (e: E) => Option +``` + +Added in v2.7.0 + +## traverse + +**Signature** + +```ts +export declare const traverse: PipeableTraverse1<'Option'> +``` + +Added in v2.6.3 + +## wilt + +**Signature** + +```ts +export declare const wilt: PipeableWilt1<'Option'> +``` + +Added in v2.6.5 -Returns `true` if the option is an instance of `Some`, `false` otherwise. +## wither **Signature** ```ts -export declare const isSome: (fa: Option) => fa is Some +export declare const wither: PipeableWither1<'Option'> ``` -**Example** +Added in v2.6.5 -```ts -import { some, none, isSome } from 'fp-ts/Option' +## zero -assert.strictEqual(isSome(some(1)), true) -assert.strictEqual(isSome(none), false) +**Signature** + +```ts +export declare const zero: () => Option ``` -Added in v2.0.0 +Added in v2.7.0 # instances @@ -889,6 +832,16 @@ export declare const Foldable: Foldable1<'Option'> Added in v2.7.0 +## FromEither + +**Signature** + +```ts +export declare const FromEither: FromEither1<'Option'> +``` + +Added in v2.11.0 + ## Functor **Signature** @@ -969,12 +922,22 @@ export declare const Witherable: Witherable1<'Option'> Added in v2.7.0 +## Zero + +**Signature** + +```ts +export declare const Zero: Zero1<'Option'> +``` + +Added in v2.11.0 + ## getEq **Signature** ```ts -export declare function getEq(E: Eq): Eq> +export declare const getEq: (E: Eq) => Eq> ``` **Example** @@ -993,68 +956,6 @@ assert.strictEqual(E.equals(some(1), some(1)), true) Added in v2.0.0 -## getFirstMonoid - -Monoid returning the left-most non-`None` value - -| x | y | concat(x, y) | -| ------- | ------- | ------------ | -| none | none | none | -| some(a) | none | some(a) | -| none | some(a) | some(a) | -| some(a) | some(b) | some(a) | - -**Signature** - -```ts -export declare function getFirstMonoid(): Monoid> -``` - -**Example** - -```ts -import { getFirstMonoid, some, none } from 'fp-ts/Option' - -const M = getFirstMonoid() -assert.deepStrictEqual(M.concat(none, none), none) -assert.deepStrictEqual(M.concat(some(1), none), some(1)) -assert.deepStrictEqual(M.concat(none, some(1)), some(1)) -assert.deepStrictEqual(M.concat(some(1), some(2)), some(1)) -``` - -Added in v2.0.0 - -## getLastMonoid - -Monoid returning the right-most non-`None` value - -| x | y | concat(x, y) | -| ------- | ------- | ------------ | -| none | none | none | -| some(a) | none | some(a) | -| none | some(a) | some(a) | -| some(a) | some(b) | some(b) | - -**Signature** - -```ts -export declare function getLastMonoid(): Monoid> -``` - -**Example** - -```ts -import { getLastMonoid, some, none } from 'fp-ts/Option' - -const M = getLastMonoid() -assert.deepStrictEqual(M.concat(none, none), none) -assert.deepStrictEqual(M.concat(some(1), none), some(1)) -assert.deepStrictEqual(M.concat(none, some(1)), some(1)) -assert.deepStrictEqual(M.concat(some(1), some(2)), some(2)) -``` - -Added in v2.0.0 - ## getMonoid Monoid returning the left-most non-`None` value. If both operands are `Some`s then the inner values are @@ -1064,13 +965,13 @@ concatenated using the provided `Semigroup` | ------- | ------- | ------------------ | | none | none | none | | some(a) | none | some(a) | -| none | some(a) | some(a) | +| none | some(b) | some(b) | | some(a) | some(b) | some(concat(a, b)) | **Signature** ```ts -export declare function getMonoid(S: Semigroup): Monoid> +export declare const getMonoid: (S: Semigroup) => Monoid> ``` **Example** @@ -1099,7 +1000,7 @@ the type the `Option` contains. **Signature** ```ts -export declare function getOrd(O: Ord): Ord> +export declare const getOrd: (O: Ord) => Ord> ``` **Example** @@ -1123,7 +1024,7 @@ Added in v2.0.0 **Signature** ```ts -export declare function getShow(S: Show): Show> +export declare const getShow: (S: Show) => Show> ``` Added in v2.0.0 @@ -1152,6 +1053,90 @@ export declare const getApplySemigroup: (S: Semigroup) => Semigroup() => Monoid> +``` + +**Example** + +```ts +import { getLastMonoid, some, none } from 'fp-ts/Option' + +const M = getLastMonoid() +assert.deepStrictEqual(M.concat(none, none), none) +assert.deepStrictEqual(M.concat(some(1), none), some(1)) +assert.deepStrictEqual(M.concat(none, some(2)), some(2)) +assert.deepStrictEqual(M.concat(some(1), some(2)), some(2)) +``` + +Added in v2.0.0 + ## ~~option~~ Use small, specific instances instead. @@ -1402,8 +1387,78 @@ export interface Some { Added in v2.0.0 +# natural transformations + +## fromEither + +Transforms an `Either` to an `Option` discarding the error. + +Alias of [getRight](#getright) + +**Signature** + +```ts +export declare const fromEither: NaturalTransformation21<'Either', 'Option'> +``` + +Added in v2.0.0 + +# refinements + +## isNone + +Returns `true` if the option is `None`, `false` otherwise. + +**Signature** + +```ts +export declare const isNone: (fa: Option) => fa is None +``` + +**Example** + +```ts +import { some, none, isNone } from 'fp-ts/Option' + +assert.strictEqual(isNone(some(1)), false) +assert.strictEqual(isNone(none), true) +``` + +Added in v2.0.0 + +## isSome + +Returns `true` if the option is an instance of `Some`, `false` otherwise. + +**Signature** + +```ts +export declare const isSome: (fa: Option) => fa is Some +``` + +**Example** + +```ts +import { some, none, isSome } from 'fp-ts/Option' + +assert.strictEqual(isSome(some(1)), true) +assert.strictEqual(isSome(none), false) +``` + +Added in v2.0.0 + # utils +## ApT + +**Signature** + +```ts +export declare const ApT: Option +``` + +Added in v2.11.0 + ## Do **Signature** @@ -1480,7 +1535,7 @@ Returns `true` if the predicate is satisfied by the wrapped value **Signature** ```ts -export declare function exists(predicate: Predicate): (ma: Option) => boolean +export declare const exists: (predicate: Predicate) => (ma: Option) => boolean ``` **Example** @@ -1514,64 +1569,74 @@ assert.strictEqual( Added in v2.0.0 -## getRefinement +## sequenceArray -Returns a `Refinement` (i.e. a custom type guard) from a `Option` returning function. -This function ensures that a custom type guard definition is type-safe. +**Signature** ```ts -import { some, none, getRefinement } from 'fp-ts/Option' +export declare const sequenceArray: (arr: readonly Option[]) => Option +``` -type A = { type: 'A' } -type B = { type: 'B' } -type C = A | B +Added in v2.9.0 -const isA = (c: C): c is A => c.type === 'B' // <= typo but typescript doesn't complain -const isA = getRefinement((c) => (c.type === 'B' ? some(c) : none)) // static error: Type '"B"' is not assignable to type '"A"' -``` +## traverseArray **Signature** ```ts -export declare function getRefinement(getOption: (a: A) => Option): Refinement +export declare const traverseArray: (f: (a: A) => Option) => (as: readonly A[]) => Option ``` -Added in v2.0.0 - -## sequenceArray +Added in v2.9.0 -Equivalent to `ReadonlyArray#sequence(Applicative)`. +## traverseArrayWithIndex **Signature** ```ts -export declare const sequenceArray: (arr: readonly Option[]) => Option +export declare const traverseArrayWithIndex: ( + f: (index: number, a: A) => Option +) => (as: readonly A[]) => Option ``` Added in v2.9.0 -## traverseArray +## traverseReadonlyArrayWithIndex -Equivalent to `ReadonlyArray#traverse(Applicative)`. +Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. **Signature** ```ts -export declare const traverseArray: (f: (a: A) => Option) => (as: readonly A[]) => Option +export declare const traverseReadonlyArrayWithIndex: ( + f: (index: number, a: A) => Option +) => (as: readonly A[]) => Option ``` -Added in v2.9.0 +Added in v2.11.0 -## traverseArrayWithIndex +## traverseReadonlyNonEmptyArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. **Signature** ```ts -export declare const traverseArrayWithIndex: ( +export declare const traverseReadonlyNonEmptyArrayWithIndex: ( f: (index: number, a: A) => Option -) => (as: readonly A[]) => Option +) => (as: ReadonlyNonEmptyArray) => Option> ``` -Added in v2.9.0 +Added in v2.11.0 + +## ~~getRefinement~~ + +Use `Refinement` module instead. + +**Signature** + +```ts +export declare function getRefinement(getOption: (a: A) => Option): Refinement +``` + +Added in v2.0.0 diff --git a/docs/modules/OptionT.ts.md b/docs/modules/OptionT.ts.md index ca4f62533..9852126ef 100644 --- a/docs/modules/OptionT.ts.md +++ b/docs/modules/OptionT.ts.md @@ -1,6 +1,6 @@ --- title: OptionT.ts -nav_order: 64 +nav_order: 69 parent: Modules --- @@ -402,42 +402,49 @@ export declare function fromPredicate( F: Pointed4 ): { (refinement: Refinement): (a: A) => Kind4> + (predicate: Predicate): (b: B) => Kind4> (predicate: Predicate): (a: A) => Kind4> } export declare function fromPredicate( F: Pointed3 ): { (refinement: Refinement): (a: A) => Kind3> + (predicate: Predicate): (b: B) => Kind3> (predicate: Predicate): (a: A) => Kind3> } export declare function fromPredicate( F: Pointed3C ): { (refinement: Refinement): (a: A) => Kind3> + (predicate: Predicate): (b: B) => Kind3> (predicate: Predicate): (a: A) => Kind3> } export declare function fromPredicate( F: Pointed2 ): { (refinement: Refinement): (a: A) => Kind2> + (predicate: Predicate): (b: B) => Kind2> (predicate: Predicate): (a: A) => Kind2> } export declare function fromPredicate( F: Pointed2C ): { (refinement: Refinement): (a: A) => Kind2> + (predicate: Predicate): (b: B) => Kind2> (predicate: Predicate): (a: A) => Kind2> } export declare function fromPredicate( F: Pointed1 ): { (refinement: Refinement): (a: A) => Kind> + (predicate: Predicate): (b: B) => Kind> (predicate: Predicate): (a: A) => Kind> } export declare function fromPredicate( F: Pointed ): { (refinement: Refinement): (a: A) => HKT> + (predicate: Predicate): (b: B) => HKT> (predicate: Predicate): (a: A) => HKT> } ``` diff --git a/docs/modules/Ord.ts.md b/docs/modules/Ord.ts.md index 028091837..148a4d525 100644 --- a/docs/modules/Ord.ts.md +++ b/docs/modules/Ord.ts.md @@ -1,6 +1,6 @@ --- title: Ord.ts -nav_order: 65 +nav_order: 70 parent: Modules --- @@ -47,12 +47,14 @@ Added in v2.0.0 - [utils](#utils) - [between](#between) - [clamp](#clamp) + - [equals](#equals) - [geq](#geq) - [gt](#gt) - [leq](#leq) - [lt](#lt) - [max](#max) - [min](#min) + - [trivial](#trivial) --- @@ -374,6 +376,16 @@ export declare const clamp: (O: Ord) => (low: A, hi: A) => (a: A) => A Added in v2.0.0 +## equals + +**Signature** + +```ts +export declare const equals: (O: Ord) => (second: A) => (first: A) => boolean +``` + +Added in v2.11.0 + ## geq Test whether one value is _non-strictly greater than_ another @@ -445,3 +457,13 @@ export declare const min: (O: Ord) => (first: A, second: A) => A ``` Added in v2.0.0 + +## trivial + +**Signature** + +```ts +export declare const trivial: Ord +``` + +Added in v2.11.0 diff --git a/docs/modules/Ordering.ts.md b/docs/modules/Ordering.ts.md index ae81f5eeb..b2d67e09d 100644 --- a/docs/modules/Ordering.ts.md +++ b/docs/modules/Ordering.ts.md @@ -1,6 +1,6 @@ --- title: Ordering.ts -nav_order: 66 +nav_order: 71 parent: Modules --- diff --git a/docs/modules/Pointed.ts.md b/docs/modules/Pointed.ts.md index f5697a148..1ad51985a 100644 --- a/docs/modules/Pointed.ts.md +++ b/docs/modules/Pointed.ts.md @@ -1,6 +1,6 @@ --- title: Pointed.ts -nav_order: 68 +nav_order: 73 parent: Modules --- diff --git a/docs/modules/Predicate.ts.md b/docs/modules/Predicate.ts.md new file mode 100644 index 000000000..fad120be6 --- /dev/null +++ b/docs/modules/Predicate.ts.md @@ -0,0 +1,159 @@ +--- +title: Predicate.ts +nav_order: 74 +parent: Modules +--- + +## Predicate overview + +Added in v2.11.0 + +--- + +

Table of contents

+ +- [Contravariant](#contravariant) + - [contramap](#contramap) +- [instances](#instances) + - [Contravariant](#contravariant-1) + - [URI](#uri) + - [URI (type alias)](#uri-type-alias) + - [getMonoidAll](#getmonoidall) + - [getMonoidAny](#getmonoidany) + - [getSemigroupAll](#getsemigroupall) + - [getSemigroupAny](#getsemigroupany) +- [utils](#utils) + - [Predicate (interface)](#predicate-interface) + - [and](#and) + - [not](#not) + - [or](#or) + +--- + +# Contravariant + +## contramap + +**Signature** + +```ts +export declare const contramap: (f: (b: B) => A) => (predicate: Predicate
) => Predicate +``` + +Added in v2.11.0 + +# instances + +## Contravariant + +**Signature** + +```ts +export declare const Contravariant: Contravariant1<'Predicate'> +``` + +Added in v2.11.0 + +## URI + +**Signature** + +```ts +export declare const URI: 'Predicate' +``` + +Added in v2.11.0 + +## URI (type alias) + +**Signature** + +```ts +export type URI = typeof URI +``` + +Added in v2.11.0 + +## getMonoidAll + +**Signature** + +```ts +export declare const getMonoidAll: () => Monoid> +``` + +Added in v2.11.0 + +## getMonoidAny + +**Signature** + +```ts +export declare const getMonoidAny: () => Monoid> +``` + +Added in v2.11.0 + +## getSemigroupAll + +**Signature** + +```ts +export declare const getSemigroupAll: () => Semigroup> +``` + +Added in v2.11.0 + +## getSemigroupAny + +**Signature** + +```ts +export declare const getSemigroupAny: () => Semigroup> +``` + +Added in v2.11.0 + +# utils + +## Predicate (interface) + +**Signature** + +```ts +export interface Predicate { + (a: A): boolean +} +``` + +Added in v2.11.0 + +## and + +**Signature** + +```ts +export declare const and: (second: Predicate) => (first: Predicate) => Predicate +``` + +Added in v2.11.0 + +## not + +**Signature** + +```ts +export declare const not: (predicate: Predicate) => Predicate +``` + +Added in v2.11.0 + +## or + +**Signature** + +```ts +export declare const or: (second: Predicate) => (first: Predicate) => Predicate +``` + +Added in v2.11.0 diff --git a/docs/modules/Profunctor.ts.md b/docs/modules/Profunctor.ts.md index 65e5bbb89..9ca9d754d 100644 --- a/docs/modules/Profunctor.ts.md +++ b/docs/modules/Profunctor.ts.md @@ -1,6 +1,6 @@ --- title: Profunctor.ts -nav_order: 69 +nav_order: 75 parent: Modules --- diff --git a/docs/modules/Random.ts.md b/docs/modules/Random.ts.md index 6cf875b75..c87b9fccb 100644 --- a/docs/modules/Random.ts.md +++ b/docs/modules/Random.ts.md @@ -1,6 +1,6 @@ --- title: Random.ts -nav_order: 70 +nav_order: 76 parent: Modules --- diff --git a/docs/modules/Reader.ts.md b/docs/modules/Reader.ts.md index 2725f2d90..934796906 100644 --- a/docs/modules/Reader.ts.md +++ b/docs/modules/Reader.ts.md @@ -1,6 +1,6 @@ --- title: Reader.ts -nav_order: 71 +nav_order: 77 parent: Modules --- @@ -37,9 +37,13 @@ Added in v2.0.0 - [combinators](#combinators) - [apFirst](#apfirst) - [apSecond](#apsecond) + - [asksReader](#asksreader) + - [asksReaderW](#asksreaderw) - [chainFirst](#chainfirst) + - [chainFirstW](#chainfirstw) - [flap](#flap) - [flatten](#flatten) + - [flattenW](#flattenw) - [local](#local) - [constructors](#constructors) - [ask](#ask) @@ -63,6 +67,7 @@ Added in v2.0.0 - [model](#model) - [Reader (interface)](#reader-interface) - [utils](#utils) + - [ApT](#apt) - [Do](#do) - [apS](#aps) - [apSW](#apsw) @@ -72,6 +77,8 @@ Added in v2.0.0 - [sequenceArray](#sequencearray) - [traverseArray](#traversearray) - [traverseArrayWithIndex](#traversearraywithindex) + - [traverseReadonlyArrayWithIndex](#traversereadonlyarraywithindex) + - [traverseReadonlyNonEmptyArrayWithIndex](#traversereadonlynonemptyarraywithindex) --- @@ -195,7 +202,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const promap: (f: (d: D) => E, g: (a: A) => B) => (fbc: Reader) => Reader +export declare const promap: (f: (d: D) => E, g: (a: A) => B) => (fea: Reader) => Reader ``` Added in v2.0.0 @@ -264,6 +271,30 @@ export declare const apSecond: (second: Reader) => (first: Reader Added in v2.0.0 +## asksReader + +Effectfully accesses the environment. + +**Signature** + +```ts +export declare const asksReader: (f: (r: R) => Reader) => Reader +``` + +Added in v2.11.0 + +## asksReaderW + +Less strict version of [`asksReader`](#asksreader). + +**Signature** + +```ts +export declare const asksReaderW: (f: (r1: R1) => Reader) => Reader +``` + +Added in v2.11.0 + ## chainFirst Composes computations in sequence, using the return value of one computation to determine the next computation and @@ -279,6 +310,22 @@ export declare const chainFirst: (f: (a: A) => Reader) => (first: Added in v2.0.0 +## chainFirstW + +Less strict version of [`chainFirst`](#chainfirst). + +Derivable from `Chain`. + +**Signature** + +```ts +export declare const chainFirstW: ( + f: (a: A) => Reader +) => (ma: Reader) => Reader +``` + +Added in v2.11.0 + ## flap Derivable from `Functor`. @@ -303,6 +350,18 @@ export declare const flatten: (mma: Reader>) => Reader(mma: Reader>) => Reader +``` + +Added in v2.11.0 + ## local Changes the value of the local context during the execution of the action `ma` (similar to `Contravariant`'s @@ -520,6 +579,16 @@ Added in v2.0.0 # utils +## ApT + +**Signature** + +```ts +export declare const ApT: Reader +``` + +Added in v2.11.0 + ## Do **Signature** @@ -594,8 +663,6 @@ Added in v2.8.0 ## sequenceArray -Equivalent to `ReadonlyArray#sequence(Applicative)`. - **Signature** ```ts @@ -606,8 +673,6 @@ Added in v2.9.0 ## traverseArray -Equivalent to `ReadonlyArray#traverse(Applicative)`. - **Signature** ```ts @@ -620,8 +685,6 @@ Added in v2.9.0 ## traverseArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. - **Signature** ```ts @@ -631,3 +694,31 @@ export declare const traverseArrayWithIndex: ( ``` Added in v2.9.0 + +## traverseReadonlyArrayWithIndex + +Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndex: ( + f: (index: number, a: A) => Reader +) => (as: readonly A[]) => Reader +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndex + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndex: ( + f: (index: number, a: A) => Reader +) => (as: ReadonlyNonEmptyArray) => Reader> +``` + +Added in v2.11.0 diff --git a/docs/modules/ReaderEither.ts.md b/docs/modules/ReaderEither.ts.md index 26cc70e8d..72d098f0d 100644 --- a/docs/modules/ReaderEither.ts.md +++ b/docs/modules/ReaderEither.ts.md @@ -1,6 +1,6 @@ --- title: ReaderEither.ts -nav_order: 72 +nav_order: 78 parent: Modules --- @@ -33,26 +33,35 @@ Added in v2.0.0 - [combinators](#combinators) - [apFirst](#apfirst) - [apSecond](#apsecond) + - [asksReaderEither](#asksreadereither) + - [asksReaderEitherW](#asksreadereitherw) - [chainEitherK](#chaineitherk) - [chainEitherKW](#chaineitherkw) - [chainFirst](#chainfirst) + - [chainFirstReaderK](#chainfirstreaderk) + - [chainFirstReaderKW](#chainfirstreaderkw) - [chainFirstW](#chainfirstw) - [chainOptionK](#chainoptionk) + - [chainReaderK](#chainreaderk) + - [chainReaderKW](#chainreaderkw) - [filterOrElse](#filterorelse) - [filterOrElseW](#filterorelsew) - [flap](#flap) - [flatten](#flatten) + - [flattenW](#flattenw) - [fromEitherK](#fromeitherk) - [fromOptionK](#fromoptionk) + - [fromReaderK](#fromreaderk) + - [local](#local) - [orElse](#orelse) + - [orElseFirst](#orelsefirst) + - [orElseFirstW](#orelsefirstw) - [orElseW](#orelsew) + - [orLeft](#orleft) - [swap](#swap) - - [~~local~~](#local) - [constructors](#constructors) - [ask](#ask) - [asks](#asks) - - [fromEither](#fromeither) - - [fromOption](#fromoption) - [fromPredicate](#frompredicate) - [left](#left) - [leftReader](#leftreader) @@ -74,6 +83,7 @@ Added in v2.0.0 - [Bifunctor](#bifunctor-1) - [Chain](#chain) - [FromEither](#fromeither) + - [FromReader](#fromreader) - [Functor](#functor-1) - [Monad](#monad-1) - [MonadThrow](#monadthrow-1) @@ -93,7 +103,12 @@ Added in v2.0.0 - [toUnion](#tounion) - [model](#model) - [ReaderEither (interface)](#readereither-interface) +- [natural transformations](#natural-transformations) + - [fromEither](#fromeither) + - [fromOption](#fromoption) + - [fromReader](#fromreader) - [utils](#utils) + - [ApT](#apt) - [Do](#do) - [apS](#aps) - [apSW](#apsw) @@ -103,6 +118,8 @@ Added in v2.0.0 - [sequenceArray](#sequencearray) - [traverseArray](#traversearray) - [traverseArrayWithIndex](#traversearraywithindex) + - [traverseReadonlyArrayWithIndex](#traversereadonlyarraywithindex) + - [traverseReadonlyNonEmptyArrayWithIndex](#traversereadonlynonemptyarraywithindex) --- @@ -299,6 +316,32 @@ export declare const apSecond: ( Added in v2.0.0 +## asksReaderEither + +Effectfully accesses the environment. + +**Signature** + +```ts +export declare const asksReaderEither: (f: (r: R) => ReaderEither) => ReaderEither +``` + +Added in v2.11.0 + +## asksReaderEitherW + +Less strict version of [`asksReaderEither`](#asksreadereither). + +**Signature** + +```ts +export declare const asksReaderEitherW: ( + f: (r1: R1) => ReaderEither +) => ReaderEither +``` + +Added in v2.11.0 + ## chainEitherK **Signature** @@ -342,6 +385,32 @@ export declare const chainFirst: ( Added in v2.0.0 +## chainFirstReaderK + +**Signature** + +```ts +export declare const chainFirstReaderK: ( + f: (a: A) => R.Reader +) => (ma: ReaderEither) => ReaderEither +``` + +Added in v2.11.0 + +## chainFirstReaderKW + +Less strict version of [`chainReaderK`](#chainreaderk). + +**Signature** + +```ts +export declare const chainFirstReaderKW: ( + f: (a: A) => R.Reader +) => (ma: ReaderEither) => ReaderEither +``` + +Added in v2.11.0 + ## chainFirstW Less strict version of [`chainFirst`](#chainfirst) @@ -370,6 +439,32 @@ export declare const chainOptionK: ( Added in v2.10.0 +## chainReaderK + +**Signature** + +```ts +export declare const chainReaderK: ( + f: (a: A) => R.Reader +) => (ma: ReaderEither) => ReaderEither +``` + +Added in v2.11.0 + +## chainReaderKW + +Less strict version of [`chainReaderK`](#chainreaderk). + +**Signature** + +```ts +export declare const chainReaderKW: ( + f: (a: A) => R.Reader +) => (ma: ReaderEither) => ReaderEither +``` + +Added in v2.11.0 + ## filterOrElse **Signature** @@ -379,6 +474,9 @@ export declare const filterOrElse: { (refinement: Refinement, onFalse: (a: A) => E): ( ma: ReaderEither ) => ReaderEither + (predicate: Predicate, onFalse: (a: A) => E): ( + mb: ReaderEither + ) => ReaderEither (predicate: Predicate, onFalse: (a: A) => E): (ma: ReaderEither) => ReaderEither } ``` @@ -396,6 +494,9 @@ export declare const filterOrElseW: { (refinement: Refinement, onFalse: (a: A) => E2): ( ma: ReaderEither ) => ReaderEither + (predicate: Predicate, onFalse: (a: A) => E2): ( + mb: ReaderEither + ) => ReaderEither (predicate: Predicate, onFalse: (a: A) => E2): ( ma: ReaderEither ) => ReaderEither @@ -428,6 +529,20 @@ export declare const flatten: (mma: ReaderEither( + mma: ReaderEither> +) => ReaderEither +``` + +Added in v2.11.0 + ## fromEitherK **Signature** @@ -452,6 +567,31 @@ export declare const fromOptionK: ( Added in v2.10.0 +## fromReaderK + +**Signature** + +```ts +export declare const fromReaderK: ( + f: (...a: A) => R.Reader +) => (...a: A) => ReaderEither +``` + +Added in v2.11.0 + +## local + +Changes the value of the local context during the execution of the action `ma` (similar to `Contravariant`'s +`contramap`). + +**Signature** + +```ts +export declare const local: (f: (r2: R2) => R1) => (ma: ReaderEither) => ReaderEither +``` + +Added in v2.0.0 + ## orElse **Signature** @@ -464,80 +604,88 @@ export declare const orElse: ( Added in v2.0.0 -## orElseW - -Less strict version of [`orElse`](#orelse). +## orElseFirst **Signature** ```ts -export declare const orElseW: ( - onLeft: (e: E1) => ReaderEither -) => (ma: ReaderEither) => ReaderEither +export declare const orElseFirst: ( + onLeft: (e: E) => ReaderEither +) => (ma: ReaderEither) => ReaderEither ``` -Added in v2.10.0 +Added in v2.11.0 -## swap +## orElseFirstW **Signature** ```ts -export declare const swap: (ma: ReaderEither) => ReaderEither +export declare const orElseFirstW: ( + onLeft: (e: E1) => ReaderEither +) => (ma: ReaderEither) => ReaderEither ``` -Added in v2.0.0 +Added in v2.11.0 -## ~~local~~ +## orElseW -Use [`local`](./Reader.ts.html#local) instead. +Less strict version of [`orElse`](#orelse). **Signature** ```ts -export declare const local: (f: (r2: R2) => R1) => (ma: ReaderEither) => ReaderEither +export declare const orElseW: ( + onLeft: (e: E1) => ReaderEither +) => (ma: ReaderEither) => ReaderEither ``` -Added in v2.0.0 +Added in v2.10.0 -# constructors - -## ask +## orLeft **Signature** ```ts -export declare const ask: () => ReaderEither +export declare const orLeft: ( + onLeft: (e: E1) => R.Reader +) => (fa: ReaderEither) => ReaderEither ``` -Added in v2.0.0 +Added in v2.11.0 -## asks +## swap **Signature** ```ts -export declare const asks: (f: (r: R) => A) => ReaderEither +export declare const swap: (ma: ReaderEither) => ReaderEither ``` Added in v2.0.0 -## fromEither +# constructors + +## ask + +Reads the current context. **Signature** ```ts -export declare const fromEither: (e: E.Either) => ReaderEither +export declare const ask: () => ReaderEither ``` Added in v2.0.0 -## fromOption +## asks + +Projects a value from the global context in a `ReaderEither`. **Signature** ```ts -export declare const fromOption: (onNone: Lazy) => (ma: Option) => ReaderEither +export declare const asks: (f: (r: R) => A) => ReaderEither ``` Added in v2.0.0 @@ -549,6 +697,7 @@ Added in v2.0.0 ```ts export declare const fromPredicate: { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => ReaderEither + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => ReaderEither (predicate: Predicate, onFalse: (a: A) => E): (a: A) => ReaderEither } ``` @@ -771,6 +920,16 @@ export declare const FromEither: FromEither3<'ReaderEither'> Added in v2.10.0 +## FromReader + +**Signature** + +```ts +export declare const FromReader: FromReader3<'ReaderEither'> +``` + +Added in v2.11.0 + ## Functor **Signature** @@ -960,8 +1119,50 @@ export interface ReaderEither extends Reader> {} Added in v2.0.0 +# natural transformations + +## fromEither + +**Signature** + +```ts +export declare const fromEither: NaturalTransformation23<'Either', 'ReaderEither'> +``` + +Added in v2.0.0 + +## fromOption + +**Signature** + +```ts +export declare const fromOption: (onNone: Lazy) => NaturalTransformation13C<'Option', 'ReaderEither', E> +``` + +Added in v2.0.0 + +## fromReader + +**Signature** + +```ts +export declare const fromReader: NaturalTransformation23R<'Reader', 'ReaderEither'> +``` + +Added in v2.11.0 + # utils +## ApT + +**Signature** + +```ts +export declare const ApT: ReaderEither +``` + +Added in v2.11.0 + ## Do **Signature** @@ -1042,8 +1243,6 @@ Added in v2.8.0 ## sequenceArray -Equivalent to `ReadonlyArray#sequence(Applicative)`. - **Signature** ```ts @@ -1054,8 +1253,6 @@ Added in v2.9.0 ## traverseArray -Equivalent to `ReadonlyArray#traverse(Applicative)`. - **Signature** ```ts @@ -1068,8 +1265,6 @@ Added in v2.9.0 ## traverseArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. - **Signature** ```ts @@ -1079,3 +1274,31 @@ export declare const traverseArrayWithIndex: ( ``` Added in v2.9.0 + +## traverseReadonlyArrayWithIndex + +Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndex: ( + f: (index: number, a: A) => ReaderEither +) => (as: readonly A[]) => ReaderEither +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndex + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndex: ( + f: (index: number, a: A) => ReaderEither +) => (as: ReadonlyNonEmptyArray) => ReaderEither> +``` + +Added in v2.11.0 diff --git a/docs/modules/ReaderT.ts.md b/docs/modules/ReaderT.ts.md index c387f5ea8..4c7be6477 100644 --- a/docs/modules/ReaderT.ts.md +++ b/docs/modules/ReaderT.ts.md @@ -1,6 +1,6 @@ --- title: ReaderT.ts -nav_order: 73 +nav_order: 79 parent: Modules --- @@ -12,6 +12,8 @@ Added in v2.0.0

Table of contents

+- [constructors](#constructors) + - [fromNaturalTransformation](#fromnaturaltransformation) - [model](#model) - [~~ReaderT1~~ (interface)](#readert1-interface) - [~~ReaderT2~~ (interface)](#readert2-interface) @@ -32,6 +34,35 @@ Added in v2.0.0 --- +# constructors + +## fromNaturalTransformation + +**Signature** + +```ts +export declare function fromNaturalTransformation( + nt: NaturalTransformation24S +): (f: (r: R) => Kind2) => Reader> +export declare function fromNaturalTransformation( + nt: NaturalTransformation23R +): (f: (r: R) => Kind2) => Reader> +export declare function fromNaturalTransformation( + nt: NaturalTransformation22 +): (f: (r: R) => Kind2) => Reader> +export declare function fromNaturalTransformation( + nt: NaturalTransformation12 +): (f: (r: R) => Kind) => Reader> +export declare function fromNaturalTransformation( + nt: NaturalTransformation11 +): (f: (r: R) => Kind) => Reader> +export declare function fromNaturalTransformation( + nt: NaturalTransformation +): (f: (r: R) => HKT) => Reader> +``` + +Added in v2.11.0 + # model ## ~~ReaderT1~~ (interface) diff --git a/docs/modules/ReaderTask.ts.md b/docs/modules/ReaderTask.ts.md index 0ce430d57..005b1d080 100644 --- a/docs/modules/ReaderTask.ts.md +++ b/docs/modules/ReaderTask.ts.md @@ -1,6 +1,6 @@ --- title: ReaderTask.ts -nav_order: 74 +nav_order: 80 parent: Modules --- @@ -25,22 +25,28 @@ Added in v2.3.0 - [combinators](#combinators) - [apFirst](#apfirst) - [apSecond](#apsecond) + - [asksReaderTask](#asksreadertask) + - [asksReaderTaskW](#asksreadertaskw) - [chainFirst](#chainfirst) - [chainFirstIOK](#chainfirstiok) + - [chainFirstReaderK](#chainfirstreaderk) + - [chainFirstReaderKW](#chainfirstreaderkw) - [chainFirstTaskK](#chainfirsttaskk) + - [chainFirstW](#chainfirstw) - [chainIOK](#chainiok) + - [chainReaderK](#chainreaderk) + - [chainReaderKW](#chainreaderkw) - [chainTaskK](#chaintaskk) - [flap](#flap) - [flatten](#flatten) + - [flattenW](#flattenw) - [fromIOK](#fromiok) + - [fromReaderK](#fromreaderk) - [fromTaskK](#fromtaskk) - - [~~local~~](#local) + - [local](#local) - [constructors](#constructors) - [ask](#ask) - [asks](#asks) - - [fromIO](#fromio) - - [fromReader](#fromreader) - - [fromTask](#fromtask) - [instances](#instances) - [ApplicativePar](#applicativepar) - [ApplicativeSeq](#applicativeseq) @@ -48,6 +54,7 @@ Added in v2.3.0 - [ApplySeq](#applyseq) - [Chain](#chain) - [FromIO](#fromio) + - [FromReader](#fromreader) - [FromTask](#fromtask) - [Functor](#functor-1) - [Monad](#monad-1) @@ -62,7 +69,12 @@ Added in v2.3.0 - [~~readerTask~~](#readertask) - [model](#model) - [ReaderTask (interface)](#readertask-interface) +- [natural transformations](#natural-transformations) + - [fromIO](#fromio) + - [fromReader](#fromreader) + - [fromTask](#fromtask) - [utils](#utils) + - [ApT](#apt) - [Do](#do) - [apS](#aps) - [apSW](#apsw) @@ -70,12 +82,16 @@ Added in v2.3.0 - [bindTo](#bindto) - [bindW](#bindw) - [sequenceArray](#sequencearray) - - [sequenceSeqArray](#sequenceseqarray) - [traverseArray](#traversearray) - [traverseArrayWithIndex](#traversearraywithindex) + - [traverseReadonlyArrayWithIndex](#traversereadonlyarraywithindex) + - [traverseReadonlyArrayWithIndexSeq](#traversereadonlyarraywithindexseq) + - [traverseReadonlyNonEmptyArrayWithIndex](#traversereadonlynonemptyarraywithindex) + - [traverseReadonlyNonEmptyArrayWithIndexSeq](#traversereadonlynonemptyarraywithindexseq) - [traverseSeqArray](#traverseseqarray) - [traverseSeqArrayWithIndex](#traverseseqarraywithindex) - [~~run~~](#run) + - [~~sequenceSeqArray~~](#sequenceseqarray) --- @@ -192,6 +208,30 @@ export declare const apSecond: (second: ReaderTask) =>
(first: Re Added in v2.3.0 +## asksReaderTask + +Effectfully accesses the environment. + +**Signature** + +```ts +export declare const asksReaderTask: (f: (r: R) => ReaderTask) => ReaderTask +``` + +Added in v2.11.0 + +## asksReaderTaskW + +Less strict version of [`asksReaderTask`](#asksreadertask). + +**Signature** + +```ts +export declare const asksReaderTaskW: (f: (r1: R1) => ReaderTask) => ReaderTask +``` + +Added in v2.11.0 + ## chainFirst Composes computations in sequence, using the return value of one computation to determine the next computation and @@ -219,6 +259,32 @@ export declare const chainFirstIOK: (f: (a: A) => IO) => (first: Rea Added in v2.10.0 +## chainFirstReaderK + +**Signature** + +```ts +export declare const chainFirstReaderK: ( + f: (a: A) => R.Reader +) => (ma: ReaderTask) => ReaderTask +``` + +Added in v2.11.0 + +## chainFirstReaderKW + +Less strict version of [`chainFirstReaderK`](#chainfirstreaderk). + +**Signature** + +```ts +export declare const chainFirstReaderKW: ( + f: (a: A) => R.Reader +) => (ma: ReaderTask) => ReaderTask +``` + +Added in v2.11.0 + ## chainFirstTaskK **Signature** @@ -229,6 +295,22 @@ export declare const chainFirstTaskK: (f: (a: A) => T.Task) => (firs Added in v2.10.0 +## chainFirstW + +Less strict version of [`chainFirst`](#chainfirst). + +Derivable from `Chain`. + +**Signature** + +```ts +export declare const chainFirstW: ( + f: (a: A) => ReaderTask +) => (ma: ReaderTask) => ReaderTask +``` + +Added in v2.11.0 + ## chainIOK **Signature** @@ -239,6 +321,30 @@ export declare const chainIOK: (f: (a: A) => IO) => (first: ReaderTa Added in v2.4.0 +## chainReaderK + +**Signature** + +```ts +export declare const chainReaderK: (f: (a: A) => R.Reader) => (ma: ReaderTask) => ReaderTask +``` + +Added in v2.11.0 + +## chainReaderKW + +Less strict version of [`chainReaderK`](#chainreaderk). + +**Signature** + +```ts +export declare const chainReaderKW: ( + f: (a: A) => R.Reader +) => (ma: ReaderTask) => ReaderTask +``` + +Added in v2.11.0 + ## chainTaskK **Signature** @@ -273,86 +379,83 @@ export declare const flatten: (mma: ReaderTask>) => Re Added in v2.3.0 -## fromIOK +## flattenW + +Less strict version of [`flatten`](#flatten). **Signature** ```ts -export declare const fromIOK: (f: (...a: A) => IO) => (...a: A) => ReaderTask +export declare const flattenW: (mma: ReaderTask>) => ReaderTask ``` -Added in v2.4.0 +Added in v2.11.0 -## fromTaskK +## fromIOK **Signature** ```ts -export declare const fromTaskK: (f: (...a: A) => T.Task) => (...a: A) => ReaderTask +export declare const fromIOK: (f: (...a: A) => IO) => (...a: A) => ReaderTask ``` Added in v2.4.0 -## ~~local~~ - -Use [`local`](./Reader.ts.html#local) instead. +## fromReaderK **Signature** ```ts -export declare const local: (f: (r2: R2) => R1) => (ma: ReaderTask) => ReaderTask +export declare const fromReaderK: (f: (...a: A) => R.Reader) => (...a: A) => ReaderTask ``` -Added in v2.3.0 - -# constructors +Added in v2.11.0 -## ask +## fromTaskK **Signature** ```ts -export declare const ask: () => ReaderTask +export declare const fromTaskK: (f: (...a: A) => T.Task) => (...a: A) => ReaderTask ``` -Added in v2.3.0 +Added in v2.4.0 -## asks +## local + +Changes the value of the local context during the execution of the action `ma` (similar to `Contravariant`'s +`contramap`). **Signature** ```ts -export declare const asks: (f: (r: R) => A) => ReaderTask +export declare const local: (f: (r2: R2) => R1) => (ma: ReaderTask) => ReaderTask ``` Added in v2.3.0 -## fromIO - -**Signature** - -```ts -export declare const fromIO: (fa: IO) => ReaderTask -``` +# constructors -Added in v2.3.0 +## ask -## fromReader +Reads the current context. **Signature** ```ts -export declare const fromReader: (ma: R.Reader) => ReaderTask +export declare const ask: () => ReaderTask ``` Added in v2.3.0 -## fromTask +## asks + +Projects a value from the global context in a `ReaderTask`. **Signature** ```ts -export declare const fromTask: (fa: T.Task) => ReaderTask +export declare const asks: (f: (r: R) => A) => ReaderTask ``` Added in v2.3.0 @@ -419,6 +522,16 @@ export declare const FromIO: FromIO2<'ReaderTask'> Added in v2.10.0 +## FromReader + +**Signature** + +```ts +export declare const FromReader: FromReader2<'ReaderTask'> +``` + +Added in v2.11.0 + ## FromTask **Signature** @@ -561,8 +674,50 @@ export interface ReaderTask { Added in v2.3.0 +# natural transformations + +## fromIO + +**Signature** + +```ts +export declare const fromIO: NaturalTransformation12<'IO', 'ReaderTask'> +``` + +Added in v2.3.0 + +## fromReader + +**Signature** + +```ts +export declare const fromReader: NaturalTransformation22<'Reader', 'ReaderTask'> +``` + +Added in v2.3.0 + +## fromTask + +**Signature** + +```ts +export declare const fromTask: NaturalTransformation12<'Task', 'ReaderTask'> +``` + +Added in v2.3.0 + # utils +## ApT + +**Signature** + +```ts +export declare const ApT: ReaderTask +``` + +Added in v2.11.0 + ## Do **Signature** @@ -637,8 +792,6 @@ Added in v2.8.0 ## sequenceArray -Equivalent to `ReadonlyArray#sequence(ApplicativePar)`. - **Signature** ```ts @@ -647,49 +800,87 @@ export declare const sequenceArray: (arr: readonly ReaderTask[]) => Added in v2.9.0 -## sequenceSeqArray +## traverseArray + +**Signature** + +```ts +export declare const traverseArray: ( + f: (a: A) => ReaderTask +) => (as: readonly A[]) => ReaderTask +``` + +Added in v2.9.0 -Equivalent to `ReadonlyArray#sequence(ApplicativeSeq)`. +## traverseArrayWithIndex **Signature** ```ts -export declare const sequenceSeqArray: (arr: readonly ReaderTask[]) => ReaderTask +export declare const traverseArrayWithIndex: ( + f: (index: number, a: A) => ReaderTask +) => (as: readonly A[]) => ReaderTask ``` -Added in v2.10.0 +Added in v2.9.0 -## traverseArray +## traverseReadonlyArrayWithIndex -Equivalent to `ReadonlyArray#traverse(ApplicativePar)`. +Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. **Signature** ```ts -export declare const traverseArray: ( - f: (a: A) => ReaderTask +export declare const traverseReadonlyArrayWithIndex: ( + f: (index: number, a: A) => ReaderTask ) => (as: readonly A[]) => ReaderTask ``` -Added in v2.9.0 +Added in v2.11.0 -## traverseArrayWithIndex +## traverseReadonlyArrayWithIndexSeq -Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. +Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. **Signature** ```ts -export declare const traverseArrayWithIndex: ( +export declare const traverseReadonlyArrayWithIndexSeq: ( f: (index: number, a: A) => ReaderTask ) => (as: readonly A[]) => ReaderTask ``` -Added in v2.9.0 +Added in v2.11.0 -## traverseSeqArray +## traverseReadonlyNonEmptyArrayWithIndex + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndex: ( + f: (index: number, a: A) => ReaderTask +) => (as: ReadonlyNonEmptyArray) => ReaderTask> +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndexSeq + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativeSeq)`. + +**Signature** -Equivalent to `ReadonlyArray#traverse(ApplicativeSeq)`. +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndexSeq: ( + f: (index: number, a: A) => ReaderTask +) => (as: ReadonlyNonEmptyArray) => ReaderTask> +``` + +Added in v2.11.0 + +## traverseSeqArray **Signature** @@ -703,8 +894,6 @@ Added in v2.10.0 ## traverseSeqArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. - **Signature** ```ts @@ -724,3 +913,15 @@ export declare function run(ma: ReaderTask, r: R): Promise ``` Added in v2.4.0 + +## ~~sequenceSeqArray~~ + +Use `traverseReadonlyArrayWithIndexSeq` instead. + +**Signature** + +```ts +export declare const sequenceSeqArray: (arr: readonly ReaderTask[]) => ReaderTask +``` + +Added in v2.10.0 diff --git a/docs/modules/ReaderTaskEither.ts.md b/docs/modules/ReaderTaskEither.ts.md index e3cf61622..ec10be853 100644 --- a/docs/modules/ReaderTaskEither.ts.md +++ b/docs/modules/ReaderTaskEither.ts.md @@ -1,6 +1,6 @@ --- title: ReaderTaskEither.ts -nav_order: 75 +nav_order: 81 parent: Modules --- @@ -33,16 +33,32 @@ Added in v2.0.0 - [combinators](#combinators) - [apFirst](#apfirst) - [apSecond](#apsecond) + - [asksReaderTaskEither](#asksreadertaskeither) + - [asksReaderTaskEitherW](#asksreadertaskeitherw) - [chainEitherK](#chaineitherk) - [chainEitherKW](#chaineitherkw) - [chainFirst](#chainfirst) - [chainFirstIOK](#chainfirstiok) + - [chainFirstReaderEitherK](#chainfirstreadereitherk) + - [chainFirstReaderEitherKW](#chainfirstreadereitherkw) + - [chainFirstReaderK](#chainfirstreaderk) + - [chainFirstReaderKW](#chainfirstreaderkw) + - [chainFirstReaderTaskK](#chainfirstreadertaskk) + - [chainFirstReaderTaskKW](#chainfirstreadertaskkw) + - [chainFirstTaskEitherK](#chainfirsttaskeitherk) + - [chainFirstTaskEitherKW](#chainfirsttaskeitherkw) - [chainFirstTaskK](#chainfirsttaskk) - [chainFirstW](#chainfirstw) - [chainIOEitherK](#chainioeitherk) - [chainIOEitherKW](#chainioeitherkw) - [chainIOK](#chainiok) - [chainOptionK](#chainoptionk) + - [chainReaderEitherK](#chainreadereitherk) + - [chainReaderEitherKW](#chainreadereitherkw) + - [chainReaderK](#chainreaderk) + - [chainReaderKW](#chainreaderkw) + - [chainReaderTaskK](#chainreadertaskk) + - [chainReaderTaskKW](#chainreadertaskkw) - [chainTaskEitherK](#chaintaskeitherk) - [chainTaskEitherKW](#chaintaskeitherkw) - [chainTaskK](#chaintaskk) @@ -50,27 +66,28 @@ Added in v2.0.0 - [filterOrElseW](#filterorelsew) - [flap](#flap) - [flatten](#flatten) + - [flattenW](#flattenw) - [fromEitherK](#fromeitherk) - [fromIOEitherK](#fromioeitherk) - [fromIOK](#fromiok) - [fromOptionK](#fromoptionk) + - [fromReaderEitherK](#fromreadereitherk) + - [fromReaderK](#fromreaderk) + - [fromReaderTaskK](#fromreadertaskk) - [fromTaskEitherK](#fromtaskeitherk) - [fromTaskK](#fromtaskk) + - [local](#local) - [orElse](#orelse) + - [orElseFirst](#orelsefirst) + - [orElseFirstW](#orelsefirstw) - [orElseW](#orelsew) + - [orLeft](#orleft) - [swap](#swap) - - [~~local~~](#local) - [constructors](#constructors) - [ask](#ask) - [asks](#asks) - - [fromEither](#fromeither) - - [fromIO](#fromio) - - [fromIOEither](#fromioeither) - - [fromOption](#fromoption) - [fromPredicate](#frompredicate) - [fromReaderEither](#fromreadereither) - - [fromTask](#fromtask) - - [fromTaskEither](#fromtaskeither) - [left](#left) - [leftIO](#leftio) - [leftReader](#leftreader) @@ -100,6 +117,7 @@ Added in v2.0.0 - [Chain](#chain) - [FromEither](#fromeither) - [FromIO](#fromio) + - [FromReader](#fromreader) - [FromTask](#fromtask) - [Functor](#functor-1) - [Monad](#monad-1) @@ -123,7 +141,16 @@ Added in v2.0.0 - [toUnion](#tounion) - [model](#model) - [ReaderTaskEither (interface)](#readertaskeither-interface) +- [natural transformations](#natural-transformations) + - [fromEither](#fromeither) + - [fromIO](#fromio) + - [fromIOEither](#fromioeither) + - [fromOption](#fromoption) + - [fromReader](#fromreader) + - [fromTask](#fromtask) + - [fromTaskEither](#fromtaskeither) - [utils](#utils) + - [ApT](#apt) - [Do](#do) - [apS](#aps) - [apSW](#apsw) @@ -135,6 +162,10 @@ Added in v2.0.0 - [sequenceSeqArray](#sequenceseqarray) - [traverseArray](#traversearray) - [traverseArrayWithIndex](#traversearraywithindex) + - [traverseReadonlyArrayWithIndex](#traversereadonlyarraywithindex) + - [traverseReadonlyArrayWithIndexSeq](#traversereadonlyarraywithindexseq) + - [traverseReadonlyNonEmptyArrayWithIndex](#traversereadonlynonemptyarraywithindex) + - [traverseReadonlyNonEmptyArrayWithIndexSeq](#traversereadonlynonemptyarraywithindexseq) - [traverseSeqArray](#traverseseqarray) - [traverseSeqArrayWithIndex](#traverseseqarraywithindex) - [~~run~~](#run) @@ -336,6 +367,34 @@ export declare const apSecond: ( Added in v2.0.0 +## asksReaderTaskEither + +Effectfully accesses the environment. + +**Signature** + +```ts +export declare const asksReaderTaskEither: ( + f: (r: R) => ReaderTaskEither +) => ReaderTaskEither +``` + +Added in v2.11.0 + +## asksReaderTaskEitherW + +Less strict version of [`asksReaderTaskEither`](#asksreadertaskeither). + +**Signature** + +```ts +export declare const asksReaderTaskEitherW: ( + f: (r1: R1) => ReaderTaskEither +) => ReaderTaskEither +``` + +Added in v2.11.0 + ## chainEitherK **Signature** @@ -391,6 +450,110 @@ export declare const chainFirstIOK: ( Added in v2.10.0 +## chainFirstReaderEitherK + +**Signature** + +```ts +export declare const chainFirstReaderEitherK: ( + f: (a: A) => ReaderEither +) => (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.11.0 + +## chainFirstReaderEitherKW + +Less strict version of [`chainFirstReaderEitherK`](#chainfirstreadereitherk). + +**Signature** + +```ts +export declare const chainFirstReaderEitherKW: ( + f: (a: A) => ReaderEither +) => (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.11.0 + +## chainFirstReaderK + +**Signature** + +```ts +export declare const chainFirstReaderK: ( + f: (a: A) => R.Reader +) => (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.11.0 + +## chainFirstReaderKW + +Less strict version of [`chainFirstReaderK`](#chainfirstreaderk). + +**Signature** + +```ts +export declare const chainFirstReaderKW: ( + f: (a: A) => R.Reader +) => (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.11.0 + +## chainFirstReaderTaskK + +**Signature** + +```ts +export declare const chainFirstReaderTaskK: ( + f: (a: A) => RT.ReaderTask +) => (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.11.0 + +## chainFirstReaderTaskKW + +Less strict version of [`chainFirstReaderTaskK`](#chainfirstreadertaskk). + +**Signature** + +```ts +export declare const chainFirstReaderTaskKW: ( + f: (a: A) => RT.ReaderTask +) => (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.11.0 + +## chainFirstTaskEitherK + +**Signature** + +```ts +export declare const chainFirstTaskEitherK: ( + f: (a: A) => TE.TaskEither +) => (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.11.0 + +## chainFirstTaskEitherKW + +Less strict version of [`chainFirstTaskEitherK`](#chainfirsttaskeitherk). + +**Signature** + +```ts +export declare const chainFirstTaskEitherKW: ( + f: (a: A) => TE.TaskEither +) => (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.11.0 + ## chainFirstTaskK **Signature** @@ -469,6 +632,84 @@ export declare const chainOptionK: ( Added in v2.10.0 +## chainReaderEitherK + +**Signature** + +```ts +export declare const chainReaderEitherK: ( + f: (a: A) => ReaderEither +) => (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.11.0 + +## chainReaderEitherKW + +Less strict version of [`chainReaderEitherK`](#chainreadereitherk). + +**Signature** + +```ts +export declare const chainReaderEitherKW: ( + f: (a: A) => ReaderEither +) => (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.11.0 + +## chainReaderK + +**Signature** + +```ts +export declare const chainReaderK: ( + f: (a: A) => R.Reader +) => (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.11.0 + +## chainReaderKW + +Less strict version of [`chainReaderK`](#chainreaderk). + +**Signature** + +```ts +export declare const chainReaderKW: ( + f: (a: A) => R.Reader +) => (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.11.0 + +## chainReaderTaskK + +**Signature** + +```ts +export declare const chainReaderTaskK: ( + f: (a: A) => RT.ReaderTask +) => (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.11.0 + +## chainReaderTaskKW + +Less strict version of [`chainReaderTaskK`](#chainreadertaskk). + +**Signature** + +```ts +export declare const chainReaderTaskKW: ( + f: (a: A) => RT.ReaderTask +) => (ma: ReaderTaskEither) => ReaderTaskEither +``` + +Added in v2.11.0 + ## chainTaskEitherK **Signature** @@ -516,6 +757,9 @@ export declare const filterOrElse: { (refinement: Refinement, onFalse: (a: A) => E): ( ma: ReaderTaskEither ) => ReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E): ( + mb: ReaderTaskEither + ) => ReaderTaskEither (predicate: Predicate, onFalse: (a: A) => E): (ma: ReaderTaskEither) => ReaderTaskEither } ``` @@ -533,6 +777,9 @@ export declare const filterOrElseW: { (refinement: Refinement, onFalse: (a: A) => E2): ( ma: ReaderTaskEither ) => ReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E2): ( + mb: ReaderTaskEither + ) => ReaderTaskEither (predicate: Predicate, onFalse: (a: A) => E2): ( ma: ReaderTaskEither ) => ReaderTaskEither @@ -567,6 +814,20 @@ export declare const flatten: ( Added in v2.0.0 +## flattenW + +Less strict version of [`flatten`](#flatten). + +**Signature** + +```ts +export declare const flattenW: ( + mma: ReaderTaskEither> +) => ReaderTaskEither +``` + +Added in v2.11.0 + ## fromEitherK **Signature** @@ -613,67 +874,68 @@ export declare const fromOptionK: ( Added in v2.10.0 -## fromTaskEitherK +## fromReaderEitherK **Signature** ```ts -export declare const fromTaskEitherK: ( - f: (...a: A) => TE.TaskEither -) => (...a: A) => ReaderTaskEither +export declare const fromReaderEitherK: ( + f: (...a: A) => ReaderEither +) => (...a: A) => ReaderTaskEither ``` -Added in v2.4.0 +Added in v2.11.0 -## fromTaskK +## fromReaderK **Signature** ```ts -export declare const fromTaskK: (f: (...a: A) => T.Task) => (...a: A) => ReaderTaskEither +export declare const fromReaderK: ( + f: (...a: A) => R.Reader +) => (...a: A) => ReaderTaskEither ``` -Added in v2.10.0 +Added in v2.11.0 -## orElse +## fromReaderTaskK **Signature** ```ts -export declare const orElse: ( - onLeft: (e: E1) => ReaderTaskEither -) => (ma: ReaderTaskEither) => ReaderTaskEither +export declare const fromReaderTaskK: ( + f: (...a: A) => RT.ReaderTask +) => (...a: A) => ReaderTaskEither ``` -Added in v2.0.0 - -## orElseW +Added in v2.11.0 -Less strict version of [`orElse`](#orelse). +## fromTaskEitherK **Signature** ```ts -export declare const orElseW: ( - onLeft: (e: E1) => ReaderTaskEither -) => (ma: ReaderTaskEither) => ReaderTaskEither +export declare const fromTaskEitherK: ( + f: (...a: A) => TE.TaskEither +) => (...a: A) => ReaderTaskEither ``` -Added in v2.10.0 +Added in v2.4.0 -## swap +## fromTaskK **Signature** ```ts -export declare const swap: (ma: ReaderTaskEither) => ReaderTaskEither +export declare const fromTaskK: (f: (...a: A) => T.Task) => (...a: A) => ReaderTaskEither ``` -Added in v2.0.0 +Added in v2.10.0 -## ~~local~~ +## local -Use [`local`](./Reader.ts.html#local) instead. +Changes the value of the local context during the execution of the action `ma` (similar to `Contravariant`'s +`contramap`). **Signature** @@ -685,107 +947,124 @@ export declare const local: ( Added in v2.0.0 -# constructors - -## ask +## orElse **Signature** ```ts -export declare const ask: () => ReaderTaskEither +export declare const orElse: ( + onLeft: (e: E1) => ReaderTaskEither +) => (ma: ReaderTaskEither) => ReaderTaskEither ``` Added in v2.0.0 -## asks +## orElseFirst **Signature** ```ts -export declare const asks: (f: (r: R) => A) => ReaderTaskEither +export declare const orElseFirst: ( + onLeft: (e: E) => ReaderTaskEither +) => (ma: ReaderTaskEither) => ReaderTaskEither ``` -Added in v2.0.0 +Added in v2.11.0 -## fromEither +## orElseFirstW **Signature** ```ts -export declare const fromEither: (e: E.Either) => ReaderTaskEither +export declare const orElseFirstW: ( + onLeft: (e: E1) => ReaderTaskEither +) => (ma: ReaderTaskEither) => ReaderTaskEither ``` -Added in v2.0.0 +Added in v2.11.0 -## fromIO +## orElseW + +Less strict version of [`orElse`](#orelse). **Signature** ```ts -export declare const fromIO: (fa: IO) => ReaderTaskEither +export declare const orElseW: ( + onLeft: (e: E1) => ReaderTaskEither +) => (ma: ReaderTaskEither) => ReaderTaskEither ``` -Added in v2.0.0 +Added in v2.10.0 -## fromIOEither +## orLeft **Signature** ```ts -export declare const fromIOEither: (ma: IOEither) => ReaderTaskEither +export declare const orLeft: ( + onLeft: (e: E1) => RT.ReaderTask +) => (fa: ReaderTaskEither) => ReaderTaskEither ``` -Added in v2.0.0 +Added in v2.11.0 -## fromOption +## swap **Signature** ```ts -export declare const fromOption: (onNone: Lazy) => (ma: Option) => ReaderTaskEither +export declare const swap: (ma: ReaderTaskEither) => ReaderTaskEither ``` Added in v2.0.0 -## fromPredicate +# constructors + +## ask + +Reads the current context. **Signature** ```ts -export declare const fromPredicate: { - (refinement: Refinement, onFalse: (a: A) => E): (a: A) => ReaderTaskEither - (predicate: Predicate, onFalse: (a: A) => E): (a: A) => ReaderTaskEither -} +export declare const ask: () => ReaderTaskEither ``` Added in v2.0.0 -## fromReaderEither +## asks + +Projects a value from the global context in a `ReaderEither`. **Signature** ```ts -export declare const fromReaderEither: (ma: ReaderEither) => ReaderTaskEither +export declare const asks: (f: (r: R) => A) => ReaderTaskEither ``` Added in v2.0.0 -## fromTask +## fromPredicate **Signature** ```ts -export declare const fromTask: (fa: T.Task) => ReaderTaskEither +export declare const fromPredicate: { + (refinement: Refinement, onFalse: (a: A) => E): (a: A) => ReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => ReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E): (a: A) => ReaderTaskEither +} ``` Added in v2.0.0 -## fromTaskEither +## fromReaderEither **Signature** ```ts -export declare const fromTaskEither: (ma: TE.TaskEither) => ReaderTaskEither +export declare const fromReaderEither: NaturalTransformation33<'ReaderEither', 'ReaderTaskEither'> ``` Added in v2.0.0 @@ -1096,6 +1375,16 @@ export declare const FromIO: FromIO3<'ReaderTaskEither'> Added in v2.10.0 +## FromReader + +**Signature** + +```ts +export declare const FromReader: FromReader3<'ReaderTaskEither'> +``` + +Added in v2.11.0 + ## FromTask **Signature** @@ -1337,8 +1626,90 @@ export interface ReaderTaskEither { Added in v2.0.0 +# natural transformations + +## fromEither + +**Signature** + +```ts +export declare const fromEither: NaturalTransformation23<'Either', 'ReaderTaskEither'> +``` + +Added in v2.0.0 + +## fromIO + +**Signature** + +```ts +export declare const fromIO: NaturalTransformation13<'IO', 'ReaderTaskEither'> +``` + +Added in v2.0.0 + +## fromIOEither + +**Signature** + +```ts +export declare const fromIOEither: NaturalTransformation23<'IOEither', 'ReaderTaskEither'> +``` + +Added in v2.0.0 + +## fromOption + +**Signature** + +```ts +export declare const fromOption: (onNone: Lazy) => NaturalTransformation13C<'Option', 'ReaderTaskEither', E> +``` + +Added in v2.0.0 + +## fromReader + +**Signature** + +```ts +export declare const fromReader: NaturalTransformation23R<'Reader', 'ReaderTaskEither'> +``` + +Added in v2.11.0 + +## fromTask + +**Signature** + +```ts +export declare const fromTask: NaturalTransformation13<'Task', 'ReaderTaskEither'> +``` + +Added in v2.0.0 + +## fromTaskEither + +**Signature** + +```ts +export declare const fromTaskEither: NaturalTransformation23<'TaskEither', 'ReaderTaskEither'> +``` + +Added in v2.0.0 + # utils +## ApT + +**Signature** + +```ts +export declare const ApT: ReaderTaskEither +``` + +Added in v2.11.0 + ## Do **Signature** @@ -1442,8 +1813,6 @@ Added in v2.0.4 ## sequenceArray -Equivalent to `ReadonlyArray#sequence(ApplicativePar)`. - **Signature** ```ts @@ -1456,8 +1825,6 @@ Added in v2.9.0 ## sequenceSeqArray -Equivalent to `ReadonlyArray#sequence(ApplicativeSeq)`. - **Signature** ```ts @@ -1470,8 +1837,6 @@ Added in v2.9.0 ## traverseArray -Equivalent to `ReadonlyArray#traverse(ApplicativePar)`. - **Signature** ```ts @@ -1484,8 +1849,6 @@ Added in v2.9.0 ## traverseArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. - **Signature** ```ts @@ -1496,9 +1859,63 @@ export declare const traverseArrayWithIndex: ( Added in v2.9.0 -## traverseSeqArray +## traverseReadonlyArrayWithIndex + +Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndex: ( + f: (index: number, a: A) => ReaderTaskEither +) => (as: readonly A[]) => ReaderTaskEither +``` + +Added in v2.11.0 + +## traverseReadonlyArrayWithIndexSeq + +Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndexSeq: ( + f: (index: number, a: A) => ReaderTaskEither +) => (as: readonly A[]) => ReaderTaskEither +``` -Equivalent to `ReadonlyArray#traverse(ApplicativeSeq)`. +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndex + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativePar)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndex: ( + f: (index: number, a: A) => ReaderTaskEither +) => (as: ReadonlyNonEmptyArray) => ReaderTaskEither> +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndexSeq + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativeSeq)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndexSeq: ( + f: (index: number, a: A) => ReaderTaskEither +) => (as: ReadonlyNonEmptyArray) => ReaderTaskEither> +``` + +Added in v2.11.0 + +## traverseSeqArray **Signature** @@ -1512,8 +1929,6 @@ Added in v2.9.0 ## traverseSeqArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. - **Signature** ```ts diff --git a/docs/modules/ReadonlyArray.ts.md b/docs/modules/ReadonlyArray.ts.md index efd7dcbcb..2133980de 100644 --- a/docs/modules/ReadonlyArray.ts.md +++ b/docs/modules/ReadonlyArray.ts.md @@ -1,6 +1,6 @@ --- title: ReadonlyArray.ts -nav_order: 76 +nav_order: 82 parent: Modules --- @@ -15,10 +15,11 @@ Added in v2.5.0 - [Alt](#alt) - [alt](#alt) - [altW](#altw) -- [Alternative](#alternative) - - [zero](#zero) - [Apply](#apply) - [ap](#ap) +- [ChainRec](#chainrec) + - [chainRecBreadthFirst](#chainrecbreadthfirst) + - [chainRecDepthFirst](#chainrecdepthfirst) - [Compactable](#compactable) - [compact](#compact) - [separate](#separate) @@ -60,6 +61,8 @@ Added in v2.5.0 - [Witherable](#witherable) - [wilt](#wilt) - [wither](#wither) +- [Zero](#zero) + - [zero](#zero) - [combinators](#combinators) - [apFirst](#apfirst) - [apSecond](#apsecond) @@ -68,6 +71,8 @@ Added in v2.5.0 - [chop](#chop) - [chunksOf](#chunksof) - [comprehension](#comprehension) + - [concat](#concat) + - [concatW](#concatw) - [difference](#difference) - [dropLeft](#dropleft) - [dropLeftWhile](#dropleftwhile) @@ -75,6 +80,8 @@ Added in v2.5.0 - [duplicate](#duplicate) - [flap](#flap) - [flatten](#flatten) + - [fromEitherK](#fromeitherk) + - [fromOptionK](#fromoptionk) - [intersection](#intersection) - [intersperse](#intersperse) - [lefts](#lefts) @@ -97,31 +104,40 @@ Added in v2.5.0 - [~~prependToAll~~](#prependtoall) - [constructors](#constructors) - [append](#append) + - [appendW](#appendw) + - [fromPredicate](#frompredicate) + - [guard](#guard) - [makeBy](#makeby) - [prepend](#prepend) - - [range](#range) + - [prependW](#prependw) - [replicate](#replicate) - [~~cons~~](#cons) + - [~~range~~](#range) - [~~snoc~~](#snoc) - [destructors](#destructors) - [foldLeft](#foldleft) - [foldRight](#foldright) + - [match](#match) - [matchLeft](#matchleft) + - [matchLeftW](#matchleftw) - [matchRight](#matchright) -- [guards](#guards) - - [isNonEmpty](#isnonempty) + - [matchRightW](#matchrightw) + - [matchW](#matchw) - [instances](#instances) - [Alt](#alt-1) - - [Alternative](#alternative-1) + - [Alternative](#alternative) - [Applicative](#applicative) - [Apply](#apply-1) - [Chain](#chain) + - [ChainRecBreadthFirst](#chainrecbreadthfirst) + - [ChainRecDepthFirst](#chainrecdepthfirst) - [Compactable](#compactable-1) - [Extend](#extend-1) - [Filterable](#filterable-1) - [FilterableWithIndex](#filterablewithindex-1) - [Foldable](#foldable-1) - [FoldableWithIndex](#foldablewithindex-1) + - [FromEither](#fromeither) - [Functor](#functor-1) - [FunctorWithIndex](#functorwithindex-1) - [Monad](#monad-1) @@ -132,15 +148,26 @@ Added in v2.5.0 - [URI (type alias)](#uri-type-alias) - [Unfoldable](#unfoldable-1) - [Witherable](#witherable-1) + - [Zero](#zero-1) + - [getDifferenceMagma](#getdifferencemagma) - [getEq](#geteq) + - [getIntersectionSemigroup](#getintersectionsemigroup) - [getMonoid](#getmonoid) - [getOrd](#getord) - [getSemigroup](#getsemigroup) - [getShow](#getshow) + - [getUnionMonoid](#getunionmonoid) + - [getUnionSemigroup](#getunionsemigroup) - [~~readonlyArray~~](#readonlyarray) - [interop](#interop) - [fromArray](#fromarray) - [toArray](#toarray) +- [natural transformations](#natural-transformations) + - [fromEither](#fromeither) + - [fromOption](#fromoption) +- [refinements](#refinements) + - [isEmpty](#isempty) + - [isNonEmpty](#isnonempty) - [unsafe](#unsafe) - [unsafeDeleteAt](#unsafedeleteat) - [unsafeInsertAt](#unsafeinsertat) @@ -155,6 +182,8 @@ Added in v2.5.0 - [elem](#elem) - [empty](#empty) - [every](#every) + - [exists](#exists) + - [filterE](#filtere) - [findFirst](#findfirst) - [findFirstMap](#findfirstmap) - [findIndex](#findindex) @@ -164,7 +193,6 @@ Added in v2.5.0 - [head](#head) - [init](#init) - [insertAt](#insertat) - - [isEmpty](#isempty) - [isOutOfBound](#isoutofbound) - [last](#last) - [lookup](#lookup) @@ -205,31 +233,41 @@ export declare const altW: (that: Lazy) => (fa: readonly A[] Added in v2.9.0 -# Alternative +# Apply -## zero +## ap + +Apply a function to an argument under a type constructor. **Signature** ```ts -export declare const zero: () => readonly A[] +export declare const ap: (fa: readonly A[]) => (fab: readonly ((a: A) => B)[]) => readonly B[] ``` -Added in v2.7.0 +Added in v2.5.0 -# Apply +# ChainRec -## ap +## chainRecBreadthFirst -Apply a function to an argument under a type constructor. +**Signature** + +```ts +export declare const chainRecBreadthFirst: (f: (a: A) => readonly Either[]) => (a: A) => readonly B[] +``` + +Added in v2.11.0 + +## chainRecDepthFirst **Signature** ```ts -export declare const ap: (fa: readonly A[]) => (fab: readonly ((a: A) => B)[]) => readonly B[] +export declare const chainRecDepthFirst: (f: (a: A) => readonly Either[]) => (a: A) => readonly B[] ``` -Added in v2.5.0 +Added in v2.11.0 # Compactable @@ -238,7 +276,7 @@ Added in v2.5.0 **Signature** ```ts -export declare const compact: (fa: readonly O.Option[]) => readonly A[] +export declare const compact: (fa: readonly Option[]) => readonly A[] ``` Added in v2.5.0 @@ -273,8 +311,9 @@ Added in v2.5.0 ```ts export declare const filter: { - (refinement: Refinement): (fa: readonly A[]) => readonly B[] - (predicate: Predicate): (fa: readonly A[]) => readonly A[] + (refinement: Refinement): (as: readonly A[]) => readonly B[] + (predicate: Predicate): (bs: readonly B[]) => readonly B[] + (predicate: Predicate): (as: readonly A[]) => readonly A[] } ``` @@ -285,7 +324,7 @@ Added in v2.5.0 **Signature** ```ts -export declare const filterMap: (f: (a: A) => O.Option) => (fa: readonly A[]) => readonly B[] +export declare const filterMap: (f: (a: A) => Option) => (fa: readonly A[]) => readonly B[] ``` Added in v2.5.0 @@ -296,8 +335,9 @@ Added in v2.5.0 ```ts export declare const partition: { - (refinement: Refinement): (fa: readonly A[]) => Separated - (predicate: Predicate): (fa: readonly A[]) => Separated + (refinement: Refinement): (as: readonly A[]) => Separated + (predicate: Predicate): (bs: readonly B[]) => Separated + (predicate: Predicate): (as: readonly A[]) => Separated } ``` @@ -322,9 +362,7 @@ Added in v2.5.0 **Signature** ```ts -export declare const filterMapWithIndex: ( - f: (i: number, a: A) => O.Option -) => (fa: readonly A[]) => readonly B[] +export declare const filterMapWithIndex: (f: (i: number, a: A) => Option) => (fa: readonly A[]) => readonly B[] ``` Added in v2.5.0 @@ -335,8 +373,9 @@ Added in v2.5.0 ```ts export declare const filterWithIndex: { - (refinementWithIndex: RefinementWithIndex): (fa: readonly A[]) => readonly B[] - (predicateWithIndex: PredicateWithIndex): (fa: readonly A[]) => readonly A[] + (refinementWithIndex: RefinementWithIndex): (as: readonly A[]) => readonly B[] + (predicateWithIndex: PredicateWithIndex): (bs: readonly B[]) => readonly B[] + (predicateWithIndex: PredicateWithIndex): (as: readonly A[]) => readonly A[] } ``` @@ -361,9 +400,12 @@ Added in v2.5.0 ```ts export declare const partitionWithIndex: { (refinementWithIndex: RefinementWithIndex): ( - fa: readonly A[] + as: readonly A[] ) => Separated - (predicateWithIndex: PredicateWithIndex): (fa: readonly A[]) => Separated + (predicateWithIndex: PredicateWithIndex): ( + bs: readonly B[] + ) => Separated + (predicateWithIndex: PredicateWithIndex): (as: readonly A[]) => Separated } ``` @@ -527,7 +569,7 @@ Added in v2.6.3 **Signature** ```ts -export declare const unfold: (b: B, f: (b: B) => O.Option) => readonly A[] +export declare const unfold: (b: B, f: (b: B) => Option) => readonly A[] ``` Added in v2.6.6 @@ -554,6 +596,18 @@ export declare const wither: PipeableWither1<'ReadonlyArray'> Added in v2.6.5 +# Zero + +## zero + +**Signature** + +```ts +export declare const zero: () => readonly A[] +``` + +Added in v2.7.0 + # combinators ## apFirst @@ -732,6 +786,26 @@ assert.deepStrictEqual( Added in v2.5.0 +## concat + +**Signature** + +```ts +export declare const concat: (second: readonly A[]) => (first: readonly A[]) => readonly A[] +``` + +Added in v2.11.0 + +## concatW + +**Signature** + +```ts +export declare const concatW: (second: readonly B[]) => (first: readonly A[]) => readonly (B | A)[] +``` + +Added in v2.11.0 + ## difference Creates an array of array values not included in the other given array using a `Eq` for equality @@ -793,7 +867,13 @@ Remove the longest initial subarray for which all element satisfy the specified **Signature** ```ts -export declare const dropLeftWhile: (predicate: Predicate) => (as: readonly A[]) => readonly A[] +export declare function dropLeftWhile( + refinement: Refinement +): (as: ReadonlyArray) => ReadonlyArray +export declare function dropLeftWhile( + predicate: Predicate +): (bs: ReadonlyArray) => ReadonlyArray +export declare function dropLeftWhile(predicate: Predicate): (as: ReadonlyArray) => ReadonlyArray ``` **Example** @@ -868,6 +948,28 @@ export declare const flatten: (mma: readonly (readonly A[])[]) => readonly A[ Added in v2.5.0 +## fromEitherK + +**Signature** + +```ts +export declare const fromEitherK: (f: (...a: A) => Either) => (...a: A) => readonly B[] +``` + +Added in v2.11.0 + +## fromOptionK + +**Signature** + +```ts +export declare const fromOptionK: ( + f: (...a: A) => Option +) => (...a: A) => readonly B[] +``` + +Added in v2.11.0 + ## intersection Creates an array of unique values that are included in all given arrays using a `Eq` for equality @@ -1194,6 +1296,9 @@ Calculate the longest initial subarray for which all element satisfy the specifi export declare function takeLeftWhile( refinement: Refinement ): (as: ReadonlyArray) => ReadonlyArray +export declare function takeLeftWhile( + predicate: Predicate +): (bs: ReadonlyArray) => ReadonlyArray export declare function takeLeftWhile(predicate: Predicate): (as: ReadonlyArray) => ReadonlyArray ``` @@ -1371,6 +1476,40 @@ assert.deepStrictEqual(pipe([1, 2, 3], append(4)), [1, 2, 3, 4]) Added in v2.10.0 +## appendW + +Less strict version of [`append`](#append). + +**Signature** + +```ts +export declare const appendW: (end: B) => (init: readonly A[]) => RNEA.ReadonlyNonEmptyArray +``` + +Added in v2.11.0 + +## fromPredicate + +**Signature** + +```ts +export declare function fromPredicate(refinement: Refinement): (a: A) => ReadonlyArray +export declare function fromPredicate(predicate: Predicate): (b: B) => ReadonlyArray +export declare function fromPredicate(predicate: Predicate): (a: A) => ReadonlyArray +``` + +Added in v2.11.0 + +## guard + +**Signature** + +```ts +export declare const guard: (b: boolean) => readonly void[] +``` + +Added in v2.11.0 + ## makeBy Return a `ReadonlyArray` of length `n` with element `i` initialized with `f(i)`. @@ -1415,25 +1554,17 @@ assert.deepStrictEqual(pipe([2, 3, 4], prepend(1)), [1, 2, 3, 4]) Added in v2.10.0 -## range +## prependW -Create a `ReadonlyArray` containing a range of integers, including both endpoints. +Less strict version of [`prepend`](#prepend). **Signature** ```ts -export declare const range: (start: number, end: number) => ReadonlyArray +export declare const prependW: (head: B) => (tail: readonly A[]) => RNEA.ReadonlyNonEmptyArray ``` -**Example** - -```ts -import { range } from 'fp-ts/ReadonlyArray' - -assert.deepStrictEqual(range(1, 5), [1, 2, 3, 4, 5]) -``` - -Added in v2.5.0 +Added in v2.11.0 ## replicate @@ -1469,6 +1600,18 @@ export declare const cons: typeof RNEA.cons Added in v2.5.0 +## ~~range~~ + +Use `ReadonlyNonEmptyArray` module instead. + +**Signature** + +```ts +export declare const range: (start: number, end: number) => RNEA.ReadonlyNonEmptyArray +``` + +Added in v2.5.0 + ## ~~snoc~~ Use [`append`](#append) instead. @@ -1513,9 +1656,22 @@ export declare const foldRight: ( Added in v2.5.0 +## match + +**Signature** + +```ts +export declare const match: ( + onEmpty: Lazy, + onNonEmpty: (as: RNEA.ReadonlyNonEmptyArray) => B +) => (as: readonly A[]) => B +``` + +Added in v2.11.0 + ## matchLeft -Break an array into its first element and remaining elements. +Break a `ReadonlyArray` into its first element and remaining elements. **Signature** @@ -1540,9 +1696,24 @@ assert.strictEqual(len([1, 2, 3]), 3) Added in v2.10.0 +## matchLeftW + +Less strict version of [`matchLeft`](#matchleft). + +**Signature** + +```ts +export declare const matchLeftW: ( + onEmpty: Lazy, + onNonEmpty: (head: A, tail: readonly A[]) => C +) => (as: readonly A[]) => B | C +``` + +Added in v2.11.0 + ## matchRight -Break an array into its initial elements and the last element. +Break a `ReadonlyArray` into its initial elements and the last element. **Signature** @@ -1555,19 +1726,35 @@ export declare const matchRight: ( Added in v2.10.0 -# guards +## matchRightW -## isNonEmpty +Less strict version of [`matchRight`](#matchright). -Test whether a `ReadonlyArray` is non empty. +**Signature** + +```ts +export declare const matchRightW: ( + onEmpty: Lazy, + onNonEmpty: (init: readonly A[], last: A) => C +) => (as: readonly A[]) => B | C +``` + +Added in v2.11.0 + +## matchW + +Less strict version of [`match`](#match). **Signature** ```ts -export declare const isNonEmpty: (as: readonly A[]) => as is RNEA.ReadonlyNonEmptyArray +export declare const matchW: ( + onEmpty: Lazy, + onNonEmpty: (as: RNEA.ReadonlyNonEmptyArray) => C +) => (as: readonly A[]) => B | C ``` -Added in v2.5.0 +Added in v2.11.0 # instances @@ -1621,6 +1808,26 @@ export declare const Chain: Chain1<'ReadonlyArray'> Added in v2.10.0 +## ChainRecBreadthFirst + +**Signature** + +```ts +export declare const ChainRecBreadthFirst: ChainRec1<'ReadonlyArray'> +``` + +Added in v2.11.0 + +## ChainRecDepthFirst + +**Signature** + +```ts +export declare const ChainRecDepthFirst: ChainRec1<'ReadonlyArray'> +``` + +Added in v2.11.0 + ## Compactable **Signature** @@ -1681,6 +1888,16 @@ export declare const FoldableWithIndex: FoldableWithIndex1<'ReadonlyArray', numb Added in v2.7.0 +## FromEither + +**Signature** + +```ts +export declare const FromEither: FromEither1<'ReadonlyArray'> +``` + +Added in v2.11.0 + ## Functor **Signature** @@ -1781,6 +1998,26 @@ export declare const Witherable: Witherable1<'ReadonlyArray'> Added in v2.7.0 +## Zero + +**Signature** + +```ts +export declare const Zero: Zero1<'ReadonlyArray'> +``` + +Added in v2.11.0 + +## getDifferenceMagma + +**Signature** + +```ts +export declare const getDifferenceMagma: (E: Eq) => Magma +``` + +Added in v2.11.0 + ## getEq Derives an `Eq` over the `ReadonlyArray` of a given element type from the `Eq` of that type. The derived `Eq` defines two @@ -1806,6 +2043,16 @@ assert.strictEqual(E.equals(['a'], []), false) Added in v2.5.0 +## getIntersectionSemigroup + +**Signature** + +```ts +export declare const getIntersectionSemigroup: (E: Eq) => Semigroup +``` + +Added in v2.11.0 + ## getMonoid Returns a `Monoid` for `ReadonlyArray`. @@ -1874,6 +2121,26 @@ export declare const getShow: (S: Show) => Show Added in v2.5.0 +## getUnionMonoid + +**Signature** + +```ts +export declare const getUnionMonoid: (E: Eq) => Monoid +``` + +Added in v2.11.0 + +## getUnionSemigroup + +**Signature** + +```ts +export declare const getUnionSemigroup: (E: Eq) => Semigroup +``` + +Added in v2.11.0 + ## ~~readonlyArray~~ Use small, specific instances instead. @@ -1916,6 +2183,64 @@ export declare const toArray: (as: readonly A[]) => A[] Added in v2.5.0 +# natural transformations + +## fromEither + +Transforms an `Either` to a `ReadonlyArray`. + +**Signature** + +```ts +export declare const fromEither: NaturalTransformation21<'Either', 'ReadonlyArray'> +``` + +Added in v2.11.0 + +## fromOption + +**Signature** + +```ts +export declare const fromOption: NaturalTransformation11<'Option', 'ReadonlyArray'> +``` + +Added in v2.11.0 + +# refinements + +## isEmpty + +Test whether a `ReadonlyArray` is empty. + +**Signature** + +```ts +export declare const isEmpty: (as: readonly A[]) => as is readonly [] +``` + +**Example** + +```ts +import { isEmpty } from 'fp-ts/ReadonlyArray' + +assert.strictEqual(isEmpty([]), true) +``` + +Added in v2.5.0 + +## isNonEmpty + +Test whether a `ReadonlyArray` is non empty. + +**Signature** + +```ts +export declare const isNonEmpty: (as: readonly A[]) => as is RNEA.ReadonlyNonEmptyArray +``` + +Added in v2.5.0 + # unsafe ## unsafeDeleteAt @@ -2016,7 +2341,7 @@ Delete the element at the specified index, creating a new array, or returning `N **Signature** ```ts -export declare const deleteAt: (i: number) => (as: readonly A[]) => O.Option +export declare const deleteAt: (i: number) => (as: readonly A[]) => Option ``` **Example** @@ -2097,6 +2422,50 @@ assert.deepStrictEqual(pipe([1, 2, -3], every(isPositive)), false) Added in v2.9.0 +## exists + +Alias of [`some`](#some) + +**Signature** + +```ts +export declare const exists: (predicate: Predicate) => (as: readonly A[]) => as is RNEA.ReadonlyNonEmptyArray +``` + +Added in v2.11.0 + +## filterE + +Filter values inside a context. + +**Signature** + +```ts +export declare const filterE: FilterE1<'ReadonlyArray'> +``` + +**Example** + +```ts +import { pipe } from 'fp-ts/function' +import * as RA from 'fp-ts/ReadonlyArray' +import * as T from 'fp-ts/Task' + +const filterE = RA.filterE(T.ApplicativePar) +async function test() { + assert.deepStrictEqual( + await pipe( + [-1, 2, 3], + filterE((n) => T.of(n > 0)) + )(), + [2, 3] + ) +} +test() +``` + +Added in v2.11.0 + ## findFirst Find the first element which satisfies a predicate (or a refinement) function @@ -2105,6 +2474,7 @@ Find the first element which satisfies a predicate (or a refinement) function ```ts export declare function findFirst(refinement: Refinement): (as: ReadonlyArray) => Option +export declare function findFirst(predicate: Predicate): (bs: ReadonlyArray) => Option export declare function findFirst(predicate: Predicate): (as: ReadonlyArray) => Option ``` @@ -2137,7 +2507,7 @@ Find the first element returned by an option based selector function **Signature** ```ts -export declare const findFirstMap: (f: (a: A) => O.Option) => (as: readonly A[]) => O.Option +export declare const findFirstMap: (f: (a: A) => Option) => (as: readonly A[]) => Option ``` **Example** @@ -2189,6 +2559,7 @@ Find the last element which satisfies a predicate function ```ts export declare function findLast(refinement: Refinement): (as: ReadonlyArray) => Option +export declare function findLast(predicate: Predicate): (bs: ReadonlyArray) => Option export declare function findLast(predicate: Predicate): (as: ReadonlyArray) => Option ``` @@ -2251,7 +2622,7 @@ Find the last element returned by an option based selector function **Signature** ```ts -export declare const findLastMap: (f: (a: A) => O.Option) => (as: readonly A[]) => O.Option +export declare const findLastMap: (f: (a: A) => Option) => (as: readonly A[]) => Option ``` **Example** @@ -2280,7 +2651,7 @@ Get the first element in an array, or `None` if the array is empty **Signature** ```ts -export declare const head: (as: readonly A[]) => O.Option +export declare const head: (as: readonly A[]) => Option ``` **Example** @@ -2302,7 +2673,7 @@ Get all but the last element of an array, creating a new array, or `None` if the **Signature** ```ts -export declare const init: (as: readonly A[]) => O.Option +export declare const init: (as: readonly A[]) => Option ``` **Example** @@ -2324,7 +2695,7 @@ Insert an element at the specified index, creating a new array, or returning `No **Signature** ```ts -export declare const insertAt: (i: number, a: A) => (as: readonly A[]) => O.Option> +export declare const insertAt: (i: number, a: A) => (as: readonly A[]) => Option> ``` **Example** @@ -2338,26 +2709,6 @@ assert.deepStrictEqual(insertAt(2, 5)([1, 2, 3, 4]), some([1, 2, 5, 3, 4])) Added in v2.5.0 -## isEmpty - -Test whether a `ReadonlyArray` is empty. - -**Signature** - -```ts -export declare const isEmpty: (as: readonly A[]) => boolean -``` - -**Example** - -```ts -import { isEmpty } from 'fp-ts/ReadonlyArray' - -assert.strictEqual(isEmpty([]), true) -``` - -Added in v2.5.0 - ## isOutOfBound Test whether an array contains a particular index @@ -2377,7 +2728,7 @@ Get the last element in an array, or `None` if the array is empty **Signature** ```ts -export declare const last: (as: readonly A[]) => O.Option +export declare const last: (as: readonly A[]) => Option ``` **Example** @@ -2424,7 +2775,7 @@ of bounds **Signature** ```ts -export declare const modifyAt: (i: number, f: (a: A) => A) => (as: readonly A[]) => O.Option +export declare const modifyAt: (i: number, f: (a: A) => A) => (as: readonly A[]) => Option ``` **Example** @@ -2487,6 +2838,7 @@ Split an array into two parts: ```ts export declare function spanLeft(refinement: Refinement): (as: ReadonlyArray) => Spanned +export declare function spanLeft(predicate: Predicate): (bs: ReadonlyArray) => Spanned export declare function spanLeft(predicate: Predicate): (as: ReadonlyArray) => Spanned ``` @@ -2507,7 +2859,7 @@ Get all but the first element of an array, creating a new array, or `None` if th **Signature** ```ts -export declare const tail: (as: readonly A[]) => O.Option +export declare const tail: (as: readonly A[]) => Option ``` **Example** @@ -2557,7 +2909,7 @@ Change the element at the specified index, creating a new array, or returning `N **Signature** ```ts -export declare const updateAt: (i: number, a: A) => (as: readonly A[]) => O.Option +export declare const updateAt: (i: number, a: A) => (as: readonly A[]) => Option ``` **Example** diff --git a/docs/modules/ReadonlyMap.ts.md b/docs/modules/ReadonlyMap.ts.md index 6d130cc25..5b025a855 100644 --- a/docs/modules/ReadonlyMap.ts.md +++ b/docs/modules/ReadonlyMap.ts.md @@ -1,6 +1,6 @@ --- title: ReadonlyMap.ts -nav_order: 77 +nav_order: 83 parent: Modules --- @@ -35,10 +35,8 @@ Added in v2.5.0 - [~~insertAt~~](#insertat) - [constructors](#constructors) - [fromFoldable](#fromfoldable) - - [fromMap](#frommap) - [singleton](#singleton) - [destructors](#destructors) - - [toMap](#tomap) - [toUnfoldable](#tounfoldable) - [instances](#instances) - [Compactable](#compactable-1) @@ -46,21 +44,32 @@ Added in v2.5.0 - [Functor](#functor-1) - [URI](#uri) - [URI (type alias)](#uri-type-alias) + - [getDifferenceMagma](#getdifferencemagma) - [getEq](#geteq) - [getFilterableWithIndex](#getfilterablewithindex) - [getFoldable](#getfoldable) - [getFoldableWithIndex](#getfoldablewithindex) - [getFunctorWithIndex](#getfunctorwithindex) + - [getIntersectionSemigroup](#getintersectionsemigroup) - [getMonoid](#getmonoid) - [getShow](#getshow) - [getTraversable](#gettraversable) - [getTraversableWithIndex](#gettraversablewithindex) + - [getUnionMonoid](#getunionmonoid) + - [getUnionSemigroup](#getunionsemigroup) - [getWitherable](#getwitherable) - [~~readonlyMap~~](#readonlymap) +- [interop](#interop) + - [fromMap](#frommap) + - [toMap](#tomap) - [utils](#utils) - [collect](#collect) + - [difference](#difference) - [elem](#elem) - [empty](#empty) + - [foldMap](#foldmap) + - [foldMapWithIndex](#foldmapwithindex) + - [intersection](#intersection) - [isEmpty](#isempty) - [isSubmap](#issubmap) - [keys](#keys) @@ -69,8 +78,13 @@ Added in v2.5.0 - [member](#member) - [modifyAt](#modifyat) - [pop](#pop) + - [reduce](#reduce) + - [reduceRight](#reduceright) + - [reduceRightWithIndex](#reducerightwithindex) + - [reduceWithIndex](#reducewithindex) - [size](#size) - [toReadonlyArray](#toreadonlyarray) + - [union](#union) - [updateAt](#updateat) - [values](#values) @@ -109,6 +123,7 @@ Added in v2.5.0 ```ts export declare const filter: { (refinement: Refinement): (fa: ReadonlyMap) => ReadonlyMap + (predicate: Predicate): (fb: ReadonlyMap) => ReadonlyMap (predicate: Predicate): (fa: ReadonlyMap) => ReadonlyMap } ``` @@ -134,6 +149,9 @@ export declare const partition: { (refinement: Refinement): ( fa: ReadonlyMap ) => Separated, ReadonlyMap> + (predicate: Predicate): ( + fb: ReadonlyMap + ) => Separated, ReadonlyMap> (predicate: Predicate): (fa: ReadonlyMap) => Separated, ReadonlyMap> } ``` @@ -210,7 +228,15 @@ Added in v2.10.0 **Signature** ```ts -export declare const filterWithIndex: (p: (k: K, a: A) => boolean) => (m: ReadonlyMap) => ReadonlyMap +export declare function filterWithIndex( + predicateWithIndex: (k: K, a: A) => a is B +): (m: ReadonlyMap) => ReadonlyMap +export declare function filterWithIndex( + predicateWithIndex: (k: K, a: A) => boolean +): (m: ReadonlyMap) => ReadonlyMap +export declare function filterWithIndex( + predicateWithIndex: (k: K, a: A) => boolean +): (m: ReadonlyMap) => ReadonlyMap ``` Added in v2.10.0 @@ -244,9 +270,15 @@ Added in v2.10.0 **Signature** ```ts -export declare const partitionWithIndex: ( - p: (k: K, a: A) => boolean -) => (fa: ReadonlyMap) => Separated, ReadonlyMap> +export declare function partitionWithIndex( + predicateWithIndex: (k: K, a: A) => a is B +): (m: ReadonlyMap) => Separated, ReadonlyMap> +export declare function partitionWithIndex( + predicateWithIndex: (k: K, a: A) => boolean +): (m: ReadonlyMap) => Separated, ReadonlyMap> +export declare function partitionWithIndex( + predicateWithIndex: (k: K, a: A) => boolean +): (m: ReadonlyMap) => Separated, ReadonlyMap> ``` Added in v2.10.0 @@ -309,16 +341,6 @@ export declare function fromFoldable( Added in v2.5.0 -## fromMap - -**Signature** - -```ts -export declare function fromMap(m: Map): ReadonlyMap -``` - -Added in v2.5.0 - ## singleton Create a map with one key/value pair @@ -333,16 +355,6 @@ Added in v2.5.0 # destructors -## toMap - -**Signature** - -```ts -export declare function toMap(m: ReadonlyMap): Map -``` - -Added in v2.5.0 - ## toUnfoldable Unfolds a map into a list of key/value pairs @@ -414,6 +426,16 @@ export type URI = typeof URI Added in v2.5.0 +## getDifferenceMagma + +**Signature** + +```ts +export declare const getDifferenceMagma: (E: Eq) => () => Magma> +``` + +Added in v2.11.0 + ## getEq **Signature** @@ -464,6 +486,16 @@ export declare const getFunctorWithIndex: () => FunctorWithIndex2C<'R Added in v2.10.0 +## getIntersectionSemigroup + +**Signature** + +```ts +export declare const getIntersectionSemigroup: (E: Eq, S: Semigroup) => Semigroup> +``` + +Added in v2.11.0 + ## getMonoid Gets `Monoid` instance for Maps given `Semigroup` instance for their values @@ -506,6 +538,26 @@ export declare const getTraversableWithIndex: (O: Ord) => TraversableWithI Added in v2.10.0 +## getUnionMonoid + +**Signature** + +```ts +export declare const getUnionMonoid: (E: Eq, S: Semigroup) => Monoid> +``` + +Added in v2.11.0 + +## getUnionSemigroup + +**Signature** + +```ts +export declare const getUnionSemigroup: (E: Eq, S: Semigroup) => Semigroup> +``` + +Added in v2.11.0 + ## getWitherable **Signature** @@ -528,6 +580,28 @@ export declare const readonlyMap: Filterable2<'ReadonlyMap'> Added in v2.5.0 +# interop + +## fromMap + +**Signature** + +```ts +export declare const fromMap: (m: Map) => ReadonlyMap +``` + +Added in v2.5.0 + +## toMap + +**Signature** + +```ts +export declare function toMap(m: ReadonlyMap): Map +``` + +Added in v2.5.0 + # utils ## collect @@ -542,6 +616,18 @@ export declare function collect( Added in v2.5.0 +## difference + +**Signature** + +```ts +export declare const difference: ( + E: Eq +) => (_second: ReadonlyMap) => (first: ReadonlyMap) => ReadonlyMap +``` + +Added in v2.11.0 + ## elem Test whether or not a value is a member of a map @@ -569,6 +655,41 @@ export declare const empty: ReadonlyMap Added in v2.5.0 +## foldMap + +**Signature** + +```ts +export declare const foldMap: (O: Ord) => (M: Monoid) => (f: (a: A) => M) => (m: ReadonlyMap) => M +``` + +Added in v2.11.0 + +## foldMapWithIndex + +**Signature** + +```ts +export declare const foldMapWithIndex: ( + O: Ord +) => (M: Monoid) => (f: (k: K, a: A) => M) => (m: ReadonlyMap) => M +``` + +Added in v2.11.0 + +## intersection + +**Signature** + +```ts +export declare const intersection: ( + E: Eq, + M: Magma +) => (second: ReadonlyMap) => (first: ReadonlyMap) => ReadonlyMap +``` + +Added in v2.11.0 + ## isEmpty Test whether or not a map is empty @@ -576,7 +697,7 @@ Test whether or not a map is empty **Signature** ```ts -export declare function isEmpty(d: ReadonlyMap): boolean +export declare const isEmpty: (m: ReadonlyMap) => boolean ``` Added in v2.5.0 @@ -687,6 +808,50 @@ export declare function pop(E: Eq): (k: K) => (m: ReadonlyMap) => Added in v2.5.0 +## reduce + +**Signature** + +```ts +export declare const reduce: (O: Ord) => (b: B, f: (b: B, a: A) => B) => (m: ReadonlyMap) => B +``` + +Added in v2.11.0 + +## reduceRight + +**Signature** + +```ts +export declare const reduceRight: (O: Ord) => (b: B, f: (a: A, b: B) => B) => (m: ReadonlyMap) => B +``` + +Added in v2.11.0 + +## reduceRightWithIndex + +**Signature** + +```ts +export declare const reduceRightWithIndex: ( + O: Ord +) => (b: B, f: (k: K, a: A, b: B) => B) => (m: ReadonlyMap) => B +``` + +Added in v2.11.0 + +## reduceWithIndex + +**Signature** + +```ts +export declare const reduceWithIndex: ( + O: Ord +) => (b: B, f: (k: K, b: B, a: A) => B) => (m: ReadonlyMap) => B +``` + +Added in v2.11.0 + ## size Calculate the number of key/value pairs in a map @@ -694,7 +859,7 @@ Calculate the number of key/value pairs in a map **Signature** ```ts -export declare function size(d: ReadonlyMap): number +export declare const size: (m: ReadonlyMap) => number ``` Added in v2.5.0 @@ -711,6 +876,19 @@ export declare const toReadonlyArray: (O: Ord) => (m: ReadonlyMap Added in v2.5.0 +## union + +**Signature** + +```ts +export declare const union: ( + E: Eq, + M: Magma +) => (second: ReadonlyMap) => (first: ReadonlyMap) => ReadonlyMap +``` + +Added in v2.11.0 + ## updateAt **Signature** diff --git a/docs/modules/ReadonlyNonEmptyArray.ts.md b/docs/modules/ReadonlyNonEmptyArray.ts.md index db7a32ade..51232b8bb 100644 --- a/docs/modules/ReadonlyNonEmptyArray.ts.md +++ b/docs/modules/ReadonlyNonEmptyArray.ts.md @@ -1,6 +1,6 @@ --- title: ReadonlyNonEmptyArray.ts -nav_order: 78 +nav_order: 84 parent: Modules --- @@ -61,31 +61,44 @@ Added in v2.5.0 - [chop](#chop) - [chunksOf](#chunksof) - [concat](#concat) + - [concatW](#concatw) - [duplicate](#duplicate) - [flap](#flap) - [flatten](#flatten) + - [getUnionSemigroup](#getunionsemigroup) - [group](#group) - [groupBy](#groupby) - - [groupSort](#groupsort) - [intersperse](#intersperse) - [modifyAt](#modifyat) - [prependAll](#prependall) - [reverse](#reverse) + - [rotate](#rotate) - [sort](#sort) + - [sortBy](#sortby) - [splitAt](#splitat) + - [union](#union) + - [uniq](#uniq) - [unzip](#unzip) - [updateAt](#updateat) + - [updateHead](#updatehead) + - [updateLast](#updatelast) - [zip](#zip) - [zipWith](#zipwith) - [~~filterWithIndex~~](#filterwithindex) - [~~filter~~](#filter) + - [~~groupSort~~](#groupsort) - [~~insertAt~~](#insertat) - [~~prependToAll~~](#prependtoall) - [constructors](#constructors) - [fromReadonlyArray](#fromreadonlyarray) + - [makeBy](#makeby) + - [range](#range) + - [replicate](#replicate) - [~~cons~~](#cons) - [~~snoc~~](#snoc) - [destructors](#destructors) + - [matchLeft](#matchleft) + - [matchRight](#matchright) - [unappend](#unappend) - [unprepend](#unprepend) - [~~uncons~~](#uncons) @@ -125,6 +138,8 @@ Added in v2.5.0 - [last](#last) - [max](#max) - [min](#min) + - [modifyHead](#modifyhead) + - [modifyLast](#modifylast) - [tail](#tail) - [~~fold~~](#fold) @@ -467,12 +482,33 @@ Added in v2.10.0 **Signature** ```ts +export declare function concat( + second: ReadonlyNonEmptyArray +): (first: ReadonlyArray) => ReadonlyNonEmptyArray +export declare function concat( + second: ReadonlyArray +): (first: ReadonlyNonEmptyArray) => ReadonlyNonEmptyArray export declare function concat(first: ReadonlyArray, second: ReadonlyNonEmptyArray): ReadonlyNonEmptyArray export declare function concat(first: ReadonlyNonEmptyArray, second: ReadonlyArray): ReadonlyNonEmptyArray ``` Added in v2.5.0 +## concatW + +**Signature** + +```ts +export declare function concatW( + second: ReadonlyNonEmptyArray +): (first: ReadonlyArray) => ReadonlyNonEmptyArray +export declare function concatW( + second: ReadonlyArray +): (first: ReadonlyNonEmptyArray) => ReadonlyNonEmptyArray +``` + +Added in v2.11.0 + ## duplicate Derivable from `Extend`. @@ -509,6 +545,16 @@ export declare const flatten: (mma: ReadonlyNonEmptyArray(E: Eq) => Se.Semigroup> +``` + +Added in v2.11.0 + ## group Group equal, consecutive elements of a `ReadonlyArray` into `ReadonlyNonEmptyArray`s. @@ -561,32 +607,6 @@ assert.deepStrictEqual(groupBy((s: string) => String(s.length))(['a', 'b', 'ab'] Added in v2.5.0 -## groupSort - -Sort and then group the elements of a `ReadonlyArray` into `ReadonlyNonEmptyArray`s. - -**Signature** - -```ts -export declare function groupSort( - O: Ord -): { - (as: ReadonlyNonEmptyArray): ReadonlyNonEmptyArray> - (as: ReadonlyArray): ReadonlyArray> -} -``` - -**Example** - -```ts -import { groupSort } from 'fp-ts/ReadonlyNonEmptyArray' -import * as N from 'fp-ts/number' - -assert.deepStrictEqual(groupSort(N.Ord)([1, 2, 1, 1]), [[1, 1, 1], [2]]) -``` - -Added in v2.5.0 - ## intersperse Places an element in between members of a `ReadonlyNonEmptyArray`. @@ -615,7 +635,7 @@ Added in v2.9.0 export declare const modifyAt: ( i: number, f: (a: A) => A -) => (as: ReadonlyNonEmptyArray) => O.Option> +) => (as: ReadonlyNonEmptyArray) => Option> ``` Added in v2.5.0 @@ -650,6 +670,27 @@ export declare const reverse: (as: ReadonlyNonEmptyArray) => ReadonlyNonEm Added in v2.5.0 +## rotate + +Rotate a `ReadonlyNonEmptyArray` by `n` steps. + +**Signature** + +```ts +export declare const rotate: (n: number) => (as: ReadonlyNonEmptyArray) => ReadonlyNonEmptyArray +``` + +**Example** + +```ts +import { rotate } from 'fp-ts/ReadonlyNonEmptyArray' + +assert.deepStrictEqual(rotate(2)([1, 2, 3, 4, 5]), [4, 5, 1, 2, 3]) +assert.deepStrictEqual(rotate(-2)([1, 2, 3, 4, 5]), [3, 4, 5, 1, 2]) +``` + +Added in v2.11.0 + ## sort **Signature** @@ -660,6 +701,62 @@ export declare const sort: (O: Ord) => (as: ReadonlyNonEmptyA Added in v2.5.0 +## sortBy + +Sort the elements of a `ReadonlyNonEmptyArray` in increasing order, where elements are compared using first `ords[0]`, then `ords[1]`, +etc... + +**Signature** + +```ts +export declare const sortBy: ( + ords: readonly Ord[] +) => (as: ReadonlyNonEmptyArray) => ReadonlyNonEmptyArray +``` + +**Example** + +```ts +import * as RNEA from 'fp-ts/ReadonlyNonEmptyArray' +import { contramap } from 'fp-ts/Ord' +import * as S from 'fp-ts/string' +import * as N from 'fp-ts/number' +import { pipe } from 'fp-ts/function' + +interface Person { + name: string + age: number +} + +const byName = pipe( + S.Ord, + contramap((p: Person) => p.name) +) + +const byAge = pipe( + N.Ord, + contramap((p: Person) => p.age) +) + +const sortByNameByAge = RNEA.sortBy([byName, byAge]) + +const persons: RNEA.ReadonlyNonEmptyArray = [ + { name: 'a', age: 1 }, + { name: 'b', age: 3 }, + { name: 'c', age: 2 }, + { name: 'b', age: 2 }, +] + +assert.deepStrictEqual(sortByNameByAge(persons), [ + { name: 'a', age: 1 }, + { name: 'b', age: 2 }, + { name: 'b', age: 3 }, + { name: 'c', age: 2 }, +]) +``` + +Added in v2.11.0 + ## splitAt Splits a `ReadonlyNonEmptyArray` into two pieces, the first piece has max `n` elements. @@ -674,6 +771,39 @@ export declare const splitAt: ( Added in v2.10.0 +## union + +**Signature** + +```ts +export declare const union: ( + E: Eq +) => (second: ReadonlyNonEmptyArray) => (first: ReadonlyNonEmptyArray) => ReadonlyNonEmptyArray +``` + +Added in v2.11.0 + +## uniq + +Remove duplicates from a `ReadonlyNonEmptyArray`, keeping the first occurrence of an element. + +**Signature** + +```ts +export declare const uniq: (E: Eq) => (as: ReadonlyNonEmptyArray) => ReadonlyNonEmptyArray +``` + +**Example** + +```ts +import { uniq } from 'fp-ts/ReadonlyNonEmptyArray' +import * as N from 'fp-ts/number' + +assert.deepStrictEqual(uniq(N.Eq)([1, 2, 1]), [1, 2]) +``` + +Added in v2.11.0 + ## unzip **Signature** @@ -694,11 +824,35 @@ Added in v2.5.1 export declare const updateAt: ( i: number, a: A -) => (as: ReadonlyNonEmptyArray) => O.Option> +) => (as: ReadonlyNonEmptyArray) => Option> ``` Added in v2.5.0 +## updateHead + +Change the head, creating a new `ReadonlyNonEmptyArray`. + +**Signature** + +```ts +export declare const updateHead: (a: A) => (as: ReadonlyNonEmptyArray) => ReadonlyNonEmptyArray +``` + +Added in v2.11.0 + +## updateLast + +Change the last element, creating a new `ReadonlyNonEmptyArray`. + +**Signature** + +```ts +export declare const updateLast: (a: A) => (as: ReadonlyNonEmptyArray) => ReadonlyNonEmptyArray +``` + +Added in v2.11.0 + ## zip **Signature** @@ -731,14 +885,14 @@ Added in v2.5.1 ## ~~filterWithIndex~~ -Use [`filterWithIndex`](./ReadonlyArray.ts.html#filterWithIndex) instead. +Use [`filterWithIndex`](./ReadonlyArray.ts.html#filterwithindex) instead. **Signature** ```ts export declare const filterWithIndex: ( predicate: (i: number, a: A) => boolean -) => (as: ReadonlyNonEmptyArray) => O.Option> +) => (as: ReadonlyNonEmptyArray) => Option> ``` Added in v2.5.0 @@ -753,6 +907,9 @@ Use [`filter`](./ReadonlyArray.ts.html#filter) instead. export declare function filter( refinement: Refinement ): (as: ReadonlyNonEmptyArray) => Option> +export declare function filter( + predicate: Predicate +): (bs: ReadonlyNonEmptyArray) => Option> export declare function filter( predicate: Predicate ): (as: ReadonlyNonEmptyArray) => Option> @@ -760,14 +917,31 @@ export declare function filter( Added in v2.5.0 +## ~~groupSort~~ + +This is just `sort` followed by `group`. + +**Signature** + +```ts +export declare function groupSort( + O: Ord +): { + (as: ReadonlyNonEmptyArray): ReadonlyNonEmptyArray> + (as: ReadonlyArray): ReadonlyArray> +} +``` + +Added in v2.5.0 + ## ~~insertAt~~ -Use [`insertAt`](./ReadonlyArray.ts.html#insertAt) instead. +Use [`insertAt`](./ReadonlyArray.ts.html#insertat) instead. **Signature** ```ts -export declare const insertAt: (i: number, a: A) => (as: readonly A[]) => O.Option> +export declare const insertAt: (i: number, a: A) => (as: readonly A[]) => Option> ``` Added in v2.5.0 @@ -793,11 +967,78 @@ Return a `ReadonlyNonEmptyArray` from a `ReadonlyArray` returning `none` if the **Signature** ```ts -export declare const fromReadonlyArray: (as: readonly A[]) => O.Option> +export declare const fromReadonlyArray: (as: readonly A[]) => Option> ``` Added in v2.5.0 +## makeBy + +Return a `ReadonlyNonEmptyArray` of length `n` with element `i` initialized with `f(i)`. + +**Note**. `n` is normalized to a natural number. + +**Signature** + +```ts +export declare const makeBy: (f: (i: number) => A) => (n: number) => ReadonlyNonEmptyArray +``` + +**Example** + +```ts +import { makeBy } from 'fp-ts/ReadonlyNonEmptyArray' +import { pipe } from 'fp-ts/function' + +const double = (n: number): number => n * 2 +assert.deepStrictEqual(pipe(5, makeBy(double)), [0, 2, 4, 6, 8]) +``` + +Added in v2.11.0 + +## range + +Create a `ReadonlyNonEmptyArray` containing a range of integers, including both endpoints. + +**Signature** + +```ts +export declare const range: (start: number, end: number) => ReadonlyNonEmptyArray +``` + +**Example** + +```ts +import { range } from 'fp-ts/ReadonlyNonEmptyArray' + +assert.deepStrictEqual(range(1, 5), [1, 2, 3, 4, 5]) +``` + +Added in v2.11.0 + +## replicate + +Create a `ReadonlyNonEmptyArray` containing a value repeated the specified number of times. + +**Note**. `n` is normalized to a natural number. + +**Signature** + +```ts +export declare const replicate: (a: A) => (n: number) => ReadonlyNonEmptyArray +``` + +**Example** + +```ts +import { replicate } from 'fp-ts/ReadonlyNonEmptyArray' +import { pipe } from 'fp-ts/function' + +assert.deepStrictEqual(pipe(3, replicate('a')), ['a', 'a', 'a']) +``` + +Added in v2.11.0 + ## ~~cons~~ Use [`prepend`](./ReadonlyArray.ts.html#prepend) instead. @@ -825,6 +1066,30 @@ Added in v2.5.0 # destructors +## matchLeft + +Break a `ReadonlyArray` into its first element and remaining elements. + +**Signature** + +```ts +export declare const matchLeft: (f: (head: A, tail: readonly A[]) => B) => (as: ReadonlyNonEmptyArray) => B +``` + +Added in v2.11.0 + +## matchRight + +Break a `ReadonlyArray` into its initial elements and the last element. + +**Signature** + +```ts +export declare const matchRight: (f: (init: readonly A[], last: A) => B) => (as: ReadonlyNonEmptyArray) => B +``` + +Added in v2.11.0 + ## unappend Return the tuple of the `init` and the `last`. @@ -1108,7 +1373,7 @@ Added in v2.5.0 **Signature** ```ts -export declare const fromArray: (as: A[]) => O.Option> +export declare const fromArray: (as: A[]) => Option> ``` Added in v2.5.0 @@ -1252,6 +1517,30 @@ export declare const min: (O: Ord) => (as: ReadonlyNonEmptyArray) => A Added in v2.5.0 +## modifyHead + +Apply a function to the head, creating a new `ReadonlyNonEmptyArray`. + +**Signature** + +```ts +export declare const modifyHead: (f: Endomorphism) => (as: ReadonlyNonEmptyArray) => ReadonlyNonEmptyArray +``` + +Added in v2.11.0 + +## modifyLast + +Apply a function to the last element, creating a new `ReadonlyNonEmptyArray`. + +**Signature** + +```ts +export declare const modifyLast: (f: Endomorphism) => (as: ReadonlyNonEmptyArray) => ReadonlyNonEmptyArray +``` + +Added in v2.11.0 + ## tail **Signature** diff --git a/docs/modules/ReadonlyRecord.ts.md b/docs/modules/ReadonlyRecord.ts.md index c7ef76734..caae504fd 100644 --- a/docs/modules/ReadonlyRecord.ts.md +++ b/docs/modules/ReadonlyRecord.ts.md @@ -1,6 +1,6 @@ --- title: ReadonlyRecord.ts -nav_order: 79 +nav_order: 85 parent: Modules --- @@ -29,10 +29,13 @@ Added in v2.5.0 - [wither](#wither) - [combinators](#combinators) - [deleteAt](#deleteat) + - [difference](#difference) - [filterMapWithIndex](#filtermapwithindex) - [flap](#flap) + - [intersection](#intersection) - [map](#map) - [mapWithIndex](#mapwithindex) + - [union](#union) - [upsertAt](#upsertat) - [~~insertAt~~](#insertat) - [constructors](#constructors) @@ -43,18 +46,27 @@ Added in v2.5.0 - [Compactable](#compactable-1) - [Filterable](#filterable-1) - [FilterableWithIndex](#filterablewithindex) - - [Foldable](#foldable-1) - - [FoldableWithIndex](#foldablewithindex) - [Functor](#functor) - [FunctorWithIndex](#functorwithindex) - - [Traversable](#traversable) - - [TraversableWithIndex](#traversablewithindex) - [URI](#uri) - [URI (type alias)](#uri-type-alias) - - [Witherable](#witherable-1) + - [getDifferenceMagma](#getdifferencemagma) - [getEq](#geteq) + - [getFoldable](#getfoldable) + - [getFoldableWithIndex](#getfoldablewithindex) + - [getIntersectionSemigroup](#getintersectionsemigroup) - [getMonoid](#getmonoid) - [getShow](#getshow) + - [getTraversable](#gettraversable) + - [getTraversableWithIndex](#gettraversablewithindex) + - [getUnionMonoid](#getunionmonoid) + - [getUnionSemigroup](#getunionsemigroup) + - [getWitherable](#getwitherable) + - [~~FoldableWithIndex~~](#foldablewithindex) + - [~~Foldable~~](#foldable) + - [~~TraversableWithIndex~~](#traversablewithindex) + - [~~Traversable~~](#traversable) + - [~~Witherable~~](#witherable) - [~~readonlyRecord~~](#readonlyrecord) - [interop](#interop) - [fromRecord](#fromrecord) @@ -99,7 +111,7 @@ Added in v2.5.0 **Signature** ```ts -export declare const compact: (r: Readonly>>) => Readonly> +export declare const compact: (r: Readonly>>) => Readonly> ``` Added in v2.5.0 @@ -125,6 +137,7 @@ Added in v2.5.0 ```ts export declare const filter: { (refinement: Refinement): (fa: Readonly>) => Readonly> + (predicate: Predicate): (fb: Readonly>) => Readonly> (predicate: Predicate): (fa: Readonly>) => Readonly> } ``` @@ -137,7 +150,7 @@ Added in v2.5.0 ```ts export declare const filterMap: ( - f: (a: A) => O.Option + f: (a: A) => Option ) => (fa: Readonly>) => Readonly> ``` @@ -152,6 +165,9 @@ export declare const partition: { (refinement: Refinement): ( fa: Readonly> ) => Separated>, Readonly>> + (predicate: Predicate): ( + fb: Readonly> + ) => Separated>, Readonly>> (predicate: Predicate): ( fa: Readonly> ) => Separated>, Readonly>> @@ -179,7 +195,10 @@ Added in v2.5.0 **Signature** ```ts -export declare const foldMap: (M: Monoid) => (f: (a: A) => M) => (fa: Readonly>) => M +export declare function foldMap( + O: Ord +): (M: Monoid) => (f: (a: A) => M) => (fa: ReadonlyRecord) => M +export declare function foldMap(M: Monoid): (f: (a: A) => M) => (fa: ReadonlyRecord) => M ``` Added in v2.5.0 @@ -189,7 +208,10 @@ Added in v2.5.0 **Signature** ```ts -export declare const reduce: (b: B, f: (b: B, a: A) => B) => (fa: Readonly>) => B +export declare function reduce( + O: Ord +): (b: B, f: (b: B, a: A) => B) => (fa: ReadonlyRecord) => B +export declare function reduce(b: B, f: (b: B, a: A) => B): (fa: ReadonlyRecord) => B ``` Added in v2.5.0 @@ -199,7 +221,10 @@ Added in v2.5.0 **Signature** ```ts -export declare const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: Readonly>) => B +export declare function reduceRight( + O: Ord +): (b: B, f: (a: A, b: B) => B) => (fa: ReadonlyRecord) => B +export declare function reduceRight(b: B, f: (a: A, b: B) => B): (fa: ReadonlyRecord) => B ``` Added in v2.5.0 @@ -242,6 +267,18 @@ export declare function deleteAt( Added in v2.5.0 +## difference + +**Signature** + +```ts +export declare const difference: ( + second: Readonly> +) => (first: Readonly>) => Readonly> +``` + +Added in v2.11.0 + ## filterMapWithIndex **Signature** @@ -266,6 +303,18 @@ export declare const flap: (a: A) => (fab: Readonly( + M: Magma +) => (second: Readonly>) => (first: Readonly>) => Readonly> +``` + +Added in v2.11.0 + ## map Map a `ReadonlyRecord` passing the values to the iterating function. @@ -292,6 +341,18 @@ export declare function mapWithIndex( Added in v2.5.0 +## union + +**Signature** + +```ts +export declare const union: ( + M: Magma +) => (second: Readonly>) => (first: Readonly>) => Readonly> +``` + +Added in v2.11.0 + ## upsertAt Insert or replace a key/value pair in a `ReadonlyRecord`. @@ -381,105 +442,95 @@ export declare const FilterableWithIndex: FilterableWithIndex1<'ReadonlyRecord', Added in v2.7.0 -## Foldable - -**Signature** - -```ts -export declare const Foldable: Foldable1<'ReadonlyRecord'> -``` - -Added in v2.7.0 - -## FoldableWithIndex +## Functor **Signature** ```ts -export declare const FoldableWithIndex: FoldableWithIndex1<'ReadonlyRecord', string> +export declare const Functor: Functor1<'ReadonlyRecord'> ``` Added in v2.7.0 -## Functor +## FunctorWithIndex **Signature** ```ts -export declare const Functor: Functor1<'ReadonlyRecord'> +export declare const FunctorWithIndex: FunctorWithIndex1<'ReadonlyRecord', string> ``` Added in v2.7.0 -## FunctorWithIndex +## URI **Signature** ```ts -export declare const FunctorWithIndex: FunctorWithIndex1<'ReadonlyRecord', string> +export declare const URI: 'ReadonlyRecord' ``` -Added in v2.7.0 +Added in v2.5.0 -## Traversable +## URI (type alias) **Signature** ```ts -export declare const Traversable: Traversable1<'ReadonlyRecord'> +export type URI = typeof URI ``` -Added in v2.7.0 +Added in v2.5.0 -## TraversableWithIndex +## getDifferenceMagma **Signature** ```ts -export declare const TraversableWithIndex: TraversableWithIndex1<'ReadonlyRecord', string> +export declare const getDifferenceMagma: () => Magma>> ``` -Added in v2.7.0 +Added in v2.11.0 -## URI +## getEq **Signature** ```ts -export declare const URI: 'ReadonlyRecord' +export declare function getEq(E: Eq): Eq> ``` Added in v2.5.0 -## URI (type alias) +## getFoldable **Signature** ```ts -export type URI = typeof URI +export declare const getFoldable: (O: Ord) => Foldable1 ``` -Added in v2.5.0 +Added in v2.11.0 -## Witherable +## getFoldableWithIndex **Signature** ```ts -export declare const Witherable: Witherable1<'ReadonlyRecord'> +export declare const getFoldableWithIndex: (O: Ord) => FoldableWithIndex1 ``` -Added in v2.7.0 +Added in v2.11.0 -## getEq +## getIntersectionSemigroup **Signature** ```ts -export declare function getEq(E: Eq): Eq> +export declare const getIntersectionSemigroup: (S: Semigroup) => Semigroup>> ``` -Added in v2.5.0 +Added in v2.11.0 ## getMonoid @@ -508,11 +559,122 @@ Added in v2.5.0 **Signature** ```ts +export declare function getShow(O: Ord): (S: Show) => Show> export declare function getShow(S: Show): Show> ``` Added in v2.5.0 +## getTraversable + +**Signature** + +```ts +export declare const getTraversable: (O: Ord) => Traversable1 +``` + +Added in v2.11.0 + +## getTraversableWithIndex + +**Signature** + +```ts +export declare const getTraversableWithIndex: (O: Ord) => TraversableWithIndex1 +``` + +Added in v2.11.0 + +## getUnionMonoid + +**Signature** + +```ts +export declare const getUnionMonoid: (S: Semigroup) => Monoid>> +``` + +Added in v2.11.0 + +## getUnionSemigroup + +**Signature** + +```ts +export declare const getUnionSemigroup: (S: Semigroup) => Semigroup>> +``` + +Added in v2.11.0 + +## getWitherable + +**Signature** + +```ts +export declare const getWitherable: (O: Ord) => Witherable1 +``` + +Added in v2.11.0 + +## ~~FoldableWithIndex~~ + +Use `getFoldableWithIndex` instead. + +**Signature** + +```ts +export declare const FoldableWithIndex: FoldableWithIndex1<'ReadonlyRecord', string> +``` + +Added in v2.7.0 + +## ~~Foldable~~ + +Use `getFoldable` instead. + +**Signature** + +```ts +export declare const Foldable: Foldable1<'ReadonlyRecord'> +``` + +Added in v2.7.0 + +## ~~TraversableWithIndex~~ + +Use `getTraversableWithIndex` instead. + +**Signature** + +```ts +export declare const TraversableWithIndex: TraversableWithIndex1<'ReadonlyRecord', string> +``` + +Added in v2.7.0 + +## ~~Traversable~~ + +Use `getTraversable` instead. + +**Signature** + +```ts +export declare const Traversable: Traversable1<'ReadonlyRecord'> +``` + +Added in v2.7.0 + +## ~~Witherable~~ + +Use `getWitherable` instead. + +**Signature** + +```ts +export declare const Witherable: Witherable1<'ReadonlyRecord'> +``` + +Added in v2.7.0 + ## ~~readonlyRecord~~ Use small, specific instances instead. @@ -536,7 +698,7 @@ Added in v2.5.0 **Signature** ```ts -export declare function fromRecord(r: Record): ReadonlyRecord +export declare const fromRecord: (r: Record) => Readonly> ``` Added in v2.5.0 @@ -546,7 +708,7 @@ Added in v2.5.0 **Signature** ```ts -export declare function toRecord(r: ReadonlyRecord): Record +export declare const toRecord: (r: Readonly>) => Record ``` Added in v2.5.0 @@ -572,18 +734,22 @@ Map a `ReadonlyRecord` into an `ReadonlyArray`. **Signature** ```ts -export declare const collect: ( +export declare function collect( + O: Ord +): (f: (k: K, a: A) => B) => (r: ReadonlyRecord) => ReadonlyArray +export declare function collect( f: (k: K, a: A) => B -) => (r: Readonly>) => readonly B[] +): (r: ReadonlyRecord) => ReadonlyArray ``` **Example** ```ts import { collect } from 'fp-ts/ReadonlyRecord' +import { Ord } from 'fp-ts/string' const x: { readonly a: string; readonly b: boolean } = { a: 'c', b: false } -assert.deepStrictEqual(collect((key, val) => ({ key: key, value: val }))(x), [ +assert.deepStrictEqual(collect(Ord)((key, val) => ({ key: key, value: val }))(x), [ { key: 'a', value: 'c' }, { key: 'b', value: false }, ]) @@ -634,6 +800,9 @@ Added in v2.5.0 export declare function filterWithIndex( refinementWithIndex: RefinementWithIndex ): (fa: ReadonlyRecord) => ReadonlyRecord +export declare function filterWithIndex( + predicateWithIndex: PredicateWithIndex +): (fb: ReadonlyRecord) => ReadonlyRecord export declare function filterWithIndex( predicateWithIndex: PredicateWithIndex ): (fa: ReadonlyRecord) => ReadonlyRecord @@ -646,6 +815,9 @@ Added in v2.5.0 **Signature** ```ts +export declare function foldMapWithIndex( + O: Ord +): (M: Monoid) => (f: (k: K, a: A) => M) => (fa: ReadonlyRecord) => M export declare function foldMapWithIndex( M: Monoid ): (f: (k: K, a: A) => M) => (fa: ReadonlyRecord) => M @@ -750,7 +922,7 @@ Added in v2.5.0 Test whether or not a key exists in a `ReadonlyRecord`. -Note. This function is not pipeable because is a custom type guard. +Note. This function is not pipeable because is a `Refinement`. **Signature** @@ -767,7 +939,7 @@ Test whether a `ReadonlyRecord` is empty. **Signature** ```ts -export declare const isEmpty: (r: ReadonlyRecord) => boolean +export declare const isEmpty: (r: Readonly>) => boolean ``` Added in v2.5.0 @@ -820,7 +992,7 @@ Added in v2.5.0 export declare const modifyAt: ( k: string, f: (a: A) => A -) => (r: Readonly>) => O.Option>> +) => (r: Readonly>) => Option>> ``` Added in v2.5.0 @@ -845,6 +1017,9 @@ Added in v2.5.0 export declare function partitionWithIndex( refinementWithIndex: RefinementWithIndex ): (fa: ReadonlyRecord) => Separated, ReadonlyRecord> +export declare function partitionWithIndex( + predicateWithIndex: PredicateWithIndex +): (fb: ReadonlyRecord) => Separated, ReadonlyRecord> export declare function partitionWithIndex( predicateWithIndex: PredicateWithIndex ): (fa: ReadonlyRecord) => Separated, ReadonlyRecord> @@ -873,6 +1048,9 @@ Added in v2.5.0 **Signature** ```ts +export declare function reduceRightWithIndex( + O: Ord +): (b: B, f: (k: K, a: A, b: B) => B) => (fa: ReadonlyRecord) => B export declare function reduceRightWithIndex( b: B, f: (k: K, a: A, b: B) => B @@ -886,6 +1064,9 @@ Added in v2.5.0 **Signature** ```ts +export declare function reduceWithIndex( + O: Ord +): (b: B, f: (k: K, b: B, a: A) => B) => (fa: ReadonlyRecord) => B export declare function reduceWithIndex( b: B, f: (k: K, b: B, a: A) => B @@ -928,7 +1109,7 @@ Calculate the number of key/value pairs in a `ReadonlyRecord`, **Signature** ```ts -export declare const size: (r: ReadonlyRecord) => number +export declare const size: (r: Readonly>) => number ``` Added in v2.5.0 @@ -1035,7 +1216,7 @@ Added in v2.5.0 export declare const updateAt: ( k: string, a: A -) => (r: Readonly>) => O.Option>> +) => (r: Readonly>) => Option>> ``` Added in v2.5.0 diff --git a/docs/modules/ReadonlySet.ts.md b/docs/modules/ReadonlySet.ts.md index 99af9c65e..83c267ff1 100644 --- a/docs/modules/ReadonlySet.ts.md +++ b/docs/modules/ReadonlySet.ts.md @@ -1,6 +1,6 @@ --- title: ReadonlySet.ts -nav_order: 80 +nav_order: 86 parent: Modules --- @@ -26,16 +26,21 @@ Added in v2.5.0 - [union](#union) - [constructors](#constructors) - [fromReadonlyArray](#fromreadonlyarray) - - [fromSet](#fromset) - [singleton](#singleton) - [~~fromArray~~](#fromarray) - [destructors](#destructors) - [toSet](#toset) - [instances](#instances) + - [URI](#uri) + - [URI (type alias)](#uri-type-alias) + - [getDifferenceMagma](#getdifferencemagma) - [getEq](#geteq) - [getIntersectionSemigroup](#getintersectionsemigroup) - [getShow](#getshow) - [getUnionMonoid](#getunionmonoid) + - [getUnionSemigroup](#getunionsemigroup) +- [interop](#interop) + - [fromSet](#fromset) - [utils](#utils) - [elem](#elem) - [empty](#empty) @@ -46,6 +51,7 @@ Added in v2.5.0 - [partition](#partition) - [partitionMap](#partitionmap) - [reduce](#reduce) + - [reduceRight](#reduceright) - [separate](#separate) - [size](#size) - [some](#some) @@ -108,6 +114,7 @@ Added in v2.5.0 ```ts export declare function filter(refinement: Refinement): (set: ReadonlySet) => ReadonlySet +export declare function filter(predicate: Predicate): (set: ReadonlySet) => ReadonlySet export declare function filter(predicate: Predicate): (set: ReadonlySet) => ReadonlySet ``` @@ -211,7 +218,7 @@ Added in v2.5.0 ## fromReadonlyArray -Create a set from an array +Create a `ReadonlySet` from a `ReadonlyArray` **Signature** @@ -221,16 +228,6 @@ export declare const fromReadonlyArray: (E: Eq) => (as: readonly A[]) => R Added in v2.10.0 -## fromSet - -**Signature** - -```ts -export declare function fromSet(s: Set): ReadonlySet -``` - -Added in v2.5.0 - ## singleton Create a set with one element @@ -269,6 +266,36 @@ Added in v2.5.0 # instances +## URI + +**Signature** + +```ts +export declare const URI: 'ReadonlySet' +``` + +Added in v2.11.0 + +## URI (type alias) + +**Signature** + +```ts +export type URI = typeof URI +``` + +Added in v2.11.0 + +## getDifferenceMagma + +**Signature** + +```ts +export declare const getDifferenceMagma: (E: Eq) => Magma> +``` + +Added in v2.11.0 + ## getEq **Signature** @@ -284,7 +311,7 @@ Added in v2.5.0 **Signature** ```ts -export declare function getIntersectionSemigroup(E: Eq): Semigroup> +export declare const getIntersectionSemigroup: (E: Eq) => Semigroup> ``` Added in v2.5.0 @@ -304,7 +331,29 @@ Added in v2.5.0 **Signature** ```ts -export declare function getUnionMonoid(E: Eq): Monoid> +export declare const getUnionMonoid: (E: Eq) => Monoid> +``` + +Added in v2.5.0 + +## getUnionSemigroup + +**Signature** + +```ts +export declare const getUnionSemigroup: (E: Eq) => Semigroup> +``` + +Added in v2.11.0 + +# interop + +## fromSet + +**Signature** + +```ts +export declare const fromSet: (s: Set) => ReadonlySet ``` Added in v2.5.0 @@ -395,6 +444,9 @@ Added in v2.5.0 export declare function partition( refinement: Refinement ): (set: ReadonlySet) => Separated, ReadonlySet> +export declare function partition( + predicate: Predicate +): (set: ReadonlySet) => Separated, ReadonlySet> export declare function partition( predicate: Predicate ): (set: ReadonlySet) => Separated, ReadonlySet> @@ -425,6 +477,16 @@ export declare function reduce(O: Ord): (b: B, f: (b: B, a: A) => B) => Added in v2.5.0 +## reduceRight + +**Signature** + +```ts +export declare const reduceRight: (O: Ord) => (b: B, f: (a: A, b: B) => B) => (fa: ReadonlySet) => B +``` + +Added in v2.11.0 + ## separate **Signature** diff --git a/docs/modules/ReadonlyTuple.ts.md b/docs/modules/ReadonlyTuple.ts.md index c6145004d..a3834ef05 100644 --- a/docs/modules/ReadonlyTuple.ts.md +++ b/docs/modules/ReadonlyTuple.ts.md @@ -1,6 +1,6 @@ --- title: ReadonlyTuple.ts -nav_order: 81 +nav_order: 87 parent: Modules --- diff --git a/docs/modules/Record.ts.md b/docs/modules/Record.ts.md index 4bcc06c26..e492749cf 100644 --- a/docs/modules/Record.ts.md +++ b/docs/modules/Record.ts.md @@ -1,6 +1,6 @@ --- title: Record.ts -nav_order: 82 +nav_order: 88 parent: Modules --- @@ -28,24 +28,36 @@ Added in v2.0.0 - [wilt](#wilt) - [wither](#wither) - [combinators](#combinators) + - [difference](#difference) - [flap](#flap) + - [intersection](#intersection) + - [union](#union) - [upsertAt](#upsertat) - [instances](#instances) - [Compactable](#compactable-1) - [Filterable](#filterable-1) - [FilterableWithIndex](#filterablewithindex) - - [Foldable](#foldable-1) - - [FoldableWithIndex](#foldablewithindex) - [Functor](#functor) - [FunctorWithIndex](#functorwithindex) - - [Traversable](#traversable) - - [TraversableWithIndex](#traversablewithindex) - [URI](#uri) - [URI (type alias)](#uri-type-alias) - - [Witherable](#witherable-1) + - [getDifferenceMagma](#getdifferencemagma) - [getEq](#geteq) + - [getFoldable](#getfoldable) + - [getFoldableWithIndex](#getfoldablewithindex) + - [getIntersectionSemigroup](#getintersectionsemigroup) - [getMonoid](#getmonoid) - [getShow](#getshow) + - [getTraversable](#gettraversable) + - [getTraversableWithIndex](#gettraversablewithindex) + - [getUnionMonoid](#getunionmonoid) + - [getUnionSemigroup](#getunionsemigroup) + - [getWitherable](#getwitherable) + - [~~FoldableWithIndex~~](#foldablewithindex) + - [~~Foldable~~](#foldable) + - [~~TraversableWithIndex~~](#traversablewithindex) + - [~~Traversable~~](#traversable) + - [~~Witherable~~](#witherable) - [~~record~~](#record) - [utils](#utils) - [collect](#collect) @@ -92,7 +104,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const compact: (fa: Record>) => Record +export declare const compact: (fa: Record>) => Record ``` Added in v2.0.0 @@ -118,6 +130,7 @@ Added in v2.0.0 ```ts export declare const filter: { (refinement: Refinement): (fa: Record) => Record + (predicate: Predicate): (fb: Record) => Record (predicate: Predicate): (fa: Record) => Record } ``` @@ -129,7 +142,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const filterMap: (f: (a: A) => O.Option) => (fa: Record) => Record +export declare const filterMap: (f: (a: A) => Option) => (fa: Record) => Record ``` Added in v2.0.0 @@ -143,6 +156,7 @@ export declare const partition: { (refinement: Refinement): ( fa: Record ) => Separated, Record> + (predicate: Predicate): (fb: Record) => Separated, Record> (predicate: Predicate): (fa: Record) => Separated, Record> } ``` @@ -168,7 +182,10 @@ Added in v2.0.0 **Signature** ```ts -export declare const foldMap: (M: Monoid) => (f: (a: A) => M) => (fa: Record) => M +export declare function foldMap( + O: Ord +): (M: Monoid) => (f: (a: A) => M) => (fa: Record) => M +export declare function foldMap(M: Monoid): (f: (a: A) => M) => (fa: Record) => M ``` Added in v2.0.0 @@ -178,7 +195,8 @@ Added in v2.0.0 **Signature** ```ts -export declare const reduce: (b: B, f: (b: B, a: A) => B) => (fa: Record) => B +export declare function reduce(O: Ord): (b: B, f: (b: B, a: A) => B) => (fa: Record) => B +export declare function reduce(b: B, f: (b: B, a: A) => B): (fa: Record) => B ``` Added in v2.0.0 @@ -188,7 +206,8 @@ Added in v2.0.0 **Signature** ```ts -export declare const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: Record) => B +export declare function reduceRight(O: Ord): (b: B, f: (a: A, b: B) => B) => (fa: Record) => B +export declare function reduceRight(b: B, f: (a: A, b: B) => B): (fa: Record) => B ``` Added in v2.0.0 @@ -217,6 +236,16 @@ Added in v2.6.5 # combinators +## difference + +**Signature** + +```ts +export declare const difference: (second: Record) => (first: Record) => Record +``` + +Added in v2.11.0 + ## flap Derivable from `Functor`. @@ -229,6 +258,30 @@ export declare const flap: (a: A) => (fab: Record B>) => Added in v2.10.0 +## intersection + +**Signature** + +```ts +export declare const intersection: ( + M: Magma +) => (second: Record) => (first: Record) => Record +``` + +Added in v2.11.0 + +## union + +**Signature** + +```ts +export declare const union: ( + M: Magma +) => (second: Record) => (first: Record) => Record +``` + +Added in v2.11.0 + ## upsertAt Insert or replace a key/value pair in a `Record`. @@ -273,105 +326,95 @@ export declare const FilterableWithIndex: FilterableWithIndex1<'Record', string> Added in v2.7.0 -## Foldable - -**Signature** - -```ts -export declare const Foldable: Foldable1<'Record'> -``` - -Added in v2.7.0 - -## FoldableWithIndex +## Functor **Signature** ```ts -export declare const FoldableWithIndex: FoldableWithIndex1<'Record', string> +export declare const Functor: Functor1<'Record'> ``` Added in v2.7.0 -## Functor +## FunctorWithIndex **Signature** ```ts -export declare const Functor: Functor1<'Record'> +export declare const FunctorWithIndex: FunctorWithIndex1<'Record', string> ``` Added in v2.7.0 -## FunctorWithIndex +## URI **Signature** ```ts -export declare const FunctorWithIndex: FunctorWithIndex1<'Record', string> +export declare const URI: 'Record' ``` -Added in v2.7.0 +Added in v2.0.0 -## Traversable +## URI (type alias) **Signature** ```ts -export declare const Traversable: Traversable1<'Record'> +export type URI = typeof URI ``` -Added in v2.7.0 +Added in v2.0.0 -## TraversableWithIndex +## getDifferenceMagma **Signature** ```ts -export declare const TraversableWithIndex: TraversableWithIndex1<'Record', string> +export declare const getDifferenceMagma: () => Magma> ``` -Added in v2.7.0 +Added in v2.11.0 -## URI +## getEq **Signature** ```ts -export declare const URI: 'Record' +export declare const getEq: (E: Eq) => Eq> ``` Added in v2.0.0 -## URI (type alias) +## getFoldable **Signature** ```ts -export type URI = typeof URI +export declare const getFoldable: (O: Ord) => Foldable1 ``` -Added in v2.0.0 +Added in v2.11.0 -## Witherable +## getFoldableWithIndex **Signature** ```ts -export declare const Witherable: Witherable1<'Record'> +export declare const getFoldableWithIndex: (O: Ord) => FoldableWithIndex1 ``` -Added in v2.7.0 +Added in v2.11.0 -## getEq +## getIntersectionSemigroup **Signature** ```ts -export declare const getEq: (E: Eq) => Eq> +export declare const getIntersectionSemigroup: (S: Semigroup) => Semigroup> ``` -Added in v2.0.0 +Added in v2.11.0 ## getMonoid @@ -400,11 +443,122 @@ Added in v2.0.0 **Signature** ```ts -export declare const getShow: (S: Show) => Show> +export declare function getShow(O: Ord): (S: Show) => Show> +export declare function getShow(S: Show): Show> ``` Added in v2.0.0 +## getTraversable + +**Signature** + +```ts +export declare const getTraversable: (O: Ord) => Traversable1 +``` + +Added in v2.11.0 + +## getTraversableWithIndex + +**Signature** + +```ts +export declare const getTraversableWithIndex: (O: Ord) => TraversableWithIndex1 +``` + +Added in v2.11.0 + +## getUnionMonoid + +**Signature** + +```ts +export declare const getUnionMonoid: (S: Semigroup) => Monoid> +``` + +Added in v2.11.0 + +## getUnionSemigroup + +**Signature** + +```ts +export declare const getUnionSemigroup: (S: Semigroup) => Semigroup> +``` + +Added in v2.11.0 + +## getWitherable + +**Signature** + +```ts +export declare const getWitherable: (O: Ord) => Witherable1 +``` + +Added in v2.11.0 + +## ~~FoldableWithIndex~~ + +Use `getFoldableWithIndex` instead. + +**Signature** + +```ts +export declare const FoldableWithIndex: FoldableWithIndex1<'Record', string> +``` + +Added in v2.7.0 + +## ~~Foldable~~ + +Use `getFoldable` instead. + +**Signature** + +```ts +export declare const Foldable: Foldable1<'Record'> +``` + +Added in v2.7.0 + +## ~~TraversableWithIndex~~ + +Use the `getTraversableWithIndex` instead. + +**Signature** + +```ts +export declare const TraversableWithIndex: TraversableWithIndex1<'Record', string> +``` + +Added in v2.7.0 + +## ~~Traversable~~ + +Use `getTraversable` instead. + +**Signature** + +```ts +export declare const Traversable: Traversable1<'Record'> +``` + +Added in v2.7.0 + +## ~~Witherable~~ + +Use `getWitherable` instead. + +**Signature** + +```ts +export declare const Witherable: Witherable1<'Record'> +``` + +Added in v2.7.0 + ## ~~record~~ Use small, specific instances instead. @@ -430,16 +584,20 @@ Map a `Record` into an `Array`. **Signature** ```ts -export declare const collect: (f: (k: K, a: A) => B) => (r: Record) => B[] +export declare function collect( + O: Ord +): (f: (k: K, a: A) => B) => (r: Record) => Array +export declare function collect(f: (k: K, a: A) => B): (r: Record) => Array ``` **Example** ```ts import { collect } from 'fp-ts/Record' +import { Ord } from 'fp-ts/string' const x: { readonly a: string; readonly b: boolean } = { a: 'c', b: false } -assert.deepStrictEqual(collect((key, val) => ({ key: key, value: val }))(x), [ +assert.deepStrictEqual(collect(Ord)((key, val) => ({ key: key, value: val }))(x), [ { key: 'a', value: 'c' }, { key: 'b', value: false }, ]) @@ -489,7 +647,7 @@ Added in v2.0.0 ```ts export declare const filterMapWithIndex: ( - f: (key: K, a: A) => O.Option + f: (key: K, a: A) => Option ) => (fa: Record) => Record ``` @@ -503,6 +661,9 @@ Added in v2.0.0 export declare function filterWithIndex( refinementWithIndex: RefinementWithIndex ): (fa: Record) => Record +export declare function filterWithIndex( + predicateWithIndex: PredicateWithIndex +): (fb: Record) => Record export declare function filterWithIndex( predicateWithIndex: PredicateWithIndex ): (fa: Record) => Record @@ -515,9 +676,12 @@ Added in v2.0.0 **Signature** ```ts -export declare const foldMapWithIndex: ( +export declare function foldMapWithIndex( + O: Ord +): (M: Monoid) => (f: (k: K, a: A) => M) => (fa: Record) => M +export declare function foldMapWithIndex( M: Monoid -) => (f: (k: K, a: A) => M) => (fa: Record) => M +): (f: (k: K, a: A) => M) => (fa: Record) => M ``` Added in v2.0.0 @@ -617,7 +781,7 @@ Added in v2.0.0 Test whether or not a key exists in a `Record`. -Note. This function is not pipeable because is a custom type guard. +Note. This function is not pipeable because is a `Refinement`. **Signature** @@ -634,7 +798,7 @@ Test whether a `Record` is empty. **Signature** ```ts -export declare const isEmpty: (r: Record) => boolean +export declare const isEmpty: (r: Record) => boolean ``` Added in v2.0.0 @@ -674,8 +838,8 @@ Lookup the value for a key in a `Record`. ```ts export declare const lookup: { - (k: string): (r: Record) => O.Option - (k: string, r: Record): O.Option + (k: string): (r: Record) => Option + (k: string, r: Record): Option } ``` @@ -713,7 +877,7 @@ Added in v2.0.0 export declare const modifyAt: ( k: string, f: (a: A) => A -) => (r: Record) => O.Option> +) => (r: Record) => Option> ``` Added in v2.0.0 @@ -738,6 +902,9 @@ Added in v2.0.0 export declare function partitionWithIndex( refinementWithIndex: RefinementWithIndex ): (fa: Record) => Separated, Record> +export declare function partitionWithIndex( + predicateWithIndex: PredicateWithIndex +): (fb: Record) => Separated, Record> export declare function partitionWithIndex( predicateWithIndex: PredicateWithIndex ): (fa: Record) => Separated, Record> @@ -764,10 +931,13 @@ Added in v2.0.0 **Signature** ```ts -export declare const reduceRightWithIndex: ( +export declare function reduceRightWithIndex( + O: Ord +): (b: B, f: (k: K, a: A, b: B) => B) => (fa: Record) => B +export declare function reduceRightWithIndex( b: B, f: (k: K, a: A, b: B) => B -) => (fa: Record) => B +): (fa: Record) => B ``` Added in v2.0.0 @@ -777,10 +947,13 @@ Added in v2.0.0 **Signature** ```ts -export declare const reduceWithIndex: ( +export declare function reduceWithIndex( + O: Ord +): (b: B, f: (k: K, b: B, a: A) => B) => (fa: Record) => B +export declare function reduceWithIndex( b: B, f: (k: K, b: B, a: A) => B -) => (fa: Record) => B +): (fa: Record) => B ``` Added in v2.0.0 @@ -831,7 +1004,7 @@ Calculate the number of key/value pairs in a `Record`. **Signature** ```ts -export declare const size: (r: Record) => number +export declare const size: (r: Record) => number ``` Added in v2.0.0 @@ -936,7 +1109,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const updateAt: (k: string, a: A) => (r: Record) => O.Option> +export declare const updateAt: (k: string, a: A) => (r: Record) => Option> ``` Added in v2.0.0 diff --git a/docs/modules/Refinement.ts.md b/docs/modules/Refinement.ts.md new file mode 100644 index 000000000..6672377d0 --- /dev/null +++ b/docs/modules/Refinement.ts.md @@ -0,0 +1,135 @@ +--- +title: Refinement.ts +nav_order: 89 +parent: Modules +--- + +## Refinement overview + +Added in v2.11.0 + +--- + +

Table of contents

+ +- [combinators](#combinators) + - [and](#and) + - [compose](#compose) + - [not](#not) + - [or](#or) + - [zero](#zero) +- [constructors](#constructors) + - [fromEitherK](#fromeitherk) + - [fromOptionK](#fromoptionk) + - [id](#id) +- [utils](#utils) + - [Refinement (interface)](#refinement-interface) + +--- + +# combinators + +## and + +**Signature** + +```ts +export declare const and: ( + second: Refinement +) => (first: Refinement) => Refinement +``` + +Added in v2.11.0 + +## compose + +**Signature** + +```ts +export declare const compose: ( + bc: Refinement +) => (ab: Refinement) => Refinement +``` + +Added in v2.11.0 + +## not + +**Signature** + +```ts +export declare const not: (refinement: Refinement) => Refinement> +``` + +Added in v2.11.0 + +## or + +**Signature** + +```ts +export declare const or: ( + second: Refinement +) => (first: Refinement) => Refinement +``` + +Added in v2.11.0 + +## zero + +**Signature** + +```ts +export declare const zero: () => Refinement +``` + +Added in v2.11.0 + +# constructors + +## fromEitherK + +**Signature** + +```ts +export declare const fromEitherK: (getEither: (a: A) => Either) => Refinement +``` + +Added in v2.11.0 + +## fromOptionK + +Returns a `Refinement` from a `Option` returning function. +This function ensures that a `Refinement` definition is type-safe. + +**Signature** + +```ts +export declare const fromOptionK: (getOption: (a: A) => Option) => Refinement +``` + +Added in v2.11.0 + +## id + +**Signature** + +```ts +export declare const id:
() => Refinement +``` + +Added in v2.11.0 + +# utils + +## Refinement (interface) + +**Signature** + +```ts +export interface Refinement { + (a: A): a is B +} +``` + +Added in v2.11.0 diff --git a/docs/modules/Ring.ts.md b/docs/modules/Ring.ts.md index 3868fa200..375f25e2b 100644 --- a/docs/modules/Ring.ts.md +++ b/docs/modules/Ring.ts.md @@ -1,6 +1,6 @@ --- title: Ring.ts -nav_order: 83 +nav_order: 90 parent: Modules --- diff --git a/docs/modules/Semigroup.ts.md b/docs/modules/Semigroup.ts.md index ccb6ec9bb..9193ee3d7 100644 --- a/docs/modules/Semigroup.ts.md +++ b/docs/modules/Semigroup.ts.md @@ -1,6 +1,6 @@ --- title: Semigroup.ts -nav_order: 84 +nav_order: 91 parent: Modules --- @@ -66,7 +66,6 @@ Added in v2.0.0 - [instances](#instances) - [first](#first) - [last](#last) - - [semigroupVoid](#semigroupvoid) - [~~getFirstSemigroup~~](#getfirstsemigroup) - [~~getFunctionSemigroup~~](#getfunctionsemigroup) - [~~getLastSemigroup~~](#getlastsemigroup) @@ -76,6 +75,7 @@ Added in v2.0.0 - [~~semigroupProduct~~](#semigroupproduct) - [~~semigroupString~~](#semigroupstring) - [~~semigroupSum~~](#semigroupsum) + - [~~semigroupVoid~~](#semigroupvoid) - [type classes](#type-classes) - [Semigroup (interface)](#semigroup-interface) - [utils](#utils) @@ -369,16 +369,6 @@ assert.deepStrictEqual(S.last().concat(1, 2), 2) Added in v2.10.0 -## semigroupVoid - -**Signature** - -```ts -export declare const semigroupVoid: Semigroup -``` - -Added in v2.0.0 - ## ~~getFirstSemigroup~~ Use [`first`](#first) instead. @@ -487,6 +477,18 @@ export declare const semigroupSum: Semigroup Added in v2.0.0 +## ~~semigroupVoid~~ + +Use `void` module instead. + +**Signature** + +```ts +export declare const semigroupVoid: Semigroup +``` + +Added in v2.0.0 + # type classes ## Semigroup (interface) diff --git a/docs/modules/Semigroupoid.ts.md b/docs/modules/Semigroupoid.ts.md index f5da9f31e..3324c3671 100644 --- a/docs/modules/Semigroupoid.ts.md +++ b/docs/modules/Semigroupoid.ts.md @@ -1,6 +1,6 @@ --- title: Semigroupoid.ts -nav_order: 85 +nav_order: 92 parent: Modules --- diff --git a/docs/modules/Semiring.ts.md b/docs/modules/Semiring.ts.md index 61152871e..0e0eaf7c3 100644 --- a/docs/modules/Semiring.ts.md +++ b/docs/modules/Semiring.ts.md @@ -1,6 +1,6 @@ --- title: Semiring.ts -nav_order: 86 +nav_order: 93 parent: Modules --- diff --git a/docs/modules/Separated.ts.md b/docs/modules/Separated.ts.md index a327b4a61..2674767f6 100644 --- a/docs/modules/Separated.ts.md +++ b/docs/modules/Separated.ts.md @@ -1,6 +1,6 @@ --- title: Separated.ts -nav_order: 87 +nav_order: 94 parent: Modules --- diff --git a/docs/modules/Set.ts.md b/docs/modules/Set.ts.md index 0ea01f00e..0795d6b77 100644 --- a/docs/modules/Set.ts.md +++ b/docs/modules/Set.ts.md @@ -1,6 +1,6 @@ --- title: Set.ts -nav_order: 88 +nav_order: 95 parent: Modules --- @@ -28,10 +28,12 @@ Added in v2.0.0 - [fromArray](#fromarray) - [singleton](#singleton) - [instances](#instances) + - [getDifferenceMagma](#getdifferencemagma) - [getEq](#geteq) - [getIntersectionSemigroup](#getintersectionsemigroup) - [getShow](#getshow) - [getUnionMonoid](#getunionmonoid) + - [getUnionSemigroup](#getunionsemigroup) - [utils](#utils) - [elem](#elem) - [empty](#empty) @@ -42,6 +44,7 @@ Added in v2.0.0 - [partition](#partition) - [partitionMap](#partitionmap) - [reduce](#reduce) + - [reduceRight](#reduceright) - [separate](#separate) - [size](#size) - [some](#some) @@ -107,6 +110,7 @@ Added in v2.0.0 ```ts export declare function filter(refinement: Refinement): (set: Set) => Set +export declare function filter(predicate: Predicate): (set: Set) => Set export declare function filter(predicate: Predicate): (set: Set) => Set ``` @@ -235,6 +239,16 @@ Added in v2.0.0 # instances +## getDifferenceMagma + +**Signature** + +```ts +export declare const getDifferenceMagma: (E: Eq) => Magma> +``` + +Added in v2.11.0 + ## getEq **Signature** @@ -250,7 +264,7 @@ Added in v2.0.0 **Signature** ```ts -export declare function getIntersectionSemigroup(E: Eq): Semigroup> +export declare const getIntersectionSemigroup: (E: Eq) => Semigroup> ``` Added in v2.0.0 @@ -270,11 +284,21 @@ Added in v2.0.0 **Signature** ```ts -export declare function getUnionMonoid(E: Eq): Monoid> +export declare const getUnionMonoid: (E: Eq) => Monoid> ``` Added in v2.0.0 +## getUnionSemigroup + +**Signature** + +```ts +export declare const getUnionSemigroup: (E: Eq) => Semigroup> +``` + +Added in v2.11.0 + # utils ## elem @@ -349,6 +373,7 @@ Added in v2.10.0 export declare function partition( refinement: Refinement ): (set: Set) => Separated, Set> +export declare function partition(predicate: Predicate): (set: Set) => Separated, Set> export declare function partition(predicate: Predicate): (set: Set) => Separated, Set> ``` @@ -377,6 +402,16 @@ export declare const reduce: (O: Ord) => (b: B, f: (b: B, a: A) => B) = Added in v2.0.0 +## reduceRight + +**Signature** + +```ts +export declare const reduceRight: (O: Ord) => (b: B, f: (a: A, b: B) => B) => (fa: Set) => B +``` + +Added in v2.11.0 + ## separate **Signature** diff --git a/docs/modules/Show.ts.md b/docs/modules/Show.ts.md index e3d348d24..f3474685d 100644 --- a/docs/modules/Show.ts.md +++ b/docs/modules/Show.ts.md @@ -1,6 +1,6 @@ --- title: Show.ts -nav_order: 89 +nav_order: 96 parent: Modules --- diff --git a/docs/modules/State.ts.md b/docs/modules/State.ts.md index ff31ce980..1d693d443 100644 --- a/docs/modules/State.ts.md +++ b/docs/modules/State.ts.md @@ -1,6 +1,6 @@ --- title: State.ts -nav_order: 90 +nav_order: 97 parent: Modules --- @@ -35,6 +35,7 @@ Added in v2.0.0 - [Applicative](#applicative) - [Apply](#apply-1) - [Chain](#chain) + - [FromState](#fromstate) - [Functor](#functor-1) - [Monad](#monad-1) - [Pointed](#pointed-1) @@ -52,6 +53,8 @@ Added in v2.0.0 - [sequenceArray](#sequencearray) - [traverseArray](#traversearray) - [traverseArrayWithIndex](#traversearraywithindex) + - [traverseReadonlyArrayWithIndex](#traversereadonlyarraywithindex) + - [traverseReadonlyNonEmptyArrayWithIndex](#traversereadonlynonemptyarraywithindex) - [~~evalState~~](#evalstate) - [~~execState~~](#execstate) @@ -263,6 +266,16 @@ export declare const Chain: Chain2<'State'> Added in v2.10.0 +## FromState + +**Signature** + +```ts +export declare const FromState: FromState2<'State'> +``` + +Added in v2.11.0 + ## Functor **Signature** @@ -403,8 +416,6 @@ Added in v2.8.0 ## sequenceArray -Equivalent to `ReadonlyArray#sequence(Applicative)`. - **Signature** ```ts @@ -415,8 +426,6 @@ Added in v2.9.0 ## traverseArray -Equivalent to `ReadonlyArray#traverse(Applicative)`. - **Signature** ```ts @@ -427,8 +436,6 @@ Added in v2.9.0 ## traverseArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. - **Signature** ```ts @@ -439,6 +446,34 @@ export declare const traverseArrayWithIndex: ( Added in v2.9.0 +## traverseReadonlyArrayWithIndex + +Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndex: ( + f: (index: number, a: A) => State +) => (as: readonly A[]) => State +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndex + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndex: ( + f: (index: number, a: A) => State +) => (as: ReadonlyNonEmptyArray) => State> +``` + +Added in v2.11.0 + ## ~~evalState~~ Use [`evaluate`](#evaluate) instead diff --git a/docs/modules/StateReaderTaskEither.ts.md b/docs/modules/StateReaderTaskEither.ts.md index 3b7cbc198..c626c7b77 100644 --- a/docs/modules/StateReaderTaskEither.ts.md +++ b/docs/modules/StateReaderTaskEither.ts.md @@ -1,6 +1,6 @@ --- title: StateReaderTaskEither.ts -nav_order: 91 +nav_order: 98 parent: Modules --- @@ -33,18 +33,25 @@ Added in v2.0.0 - [combinators](#combinators) - [apFirst](#apfirst) - [apSecond](#apsecond) + - [asksStateReaderTaskEither](#asksstatereadertaskeither) + - [asksStateReaderTaskEitherW](#asksstatereadertaskeitherw) - [chainEitherK](#chaineitherk) - [chainEitherKW](#chaineitherkw) - [chainFirst](#chainfirst) - [chainFirstIOK](#chainfirstiok) + - [chainFirstReaderK](#chainfirstreaderk) + - [chainFirstReaderKW](#chainfirstreaderkw) - [chainFirstTaskK](#chainfirsttaskk) - [chainFirstW](#chainfirstw) - [chainIOEitherK](#chainioeitherk) - [chainIOEitherKW](#chainioeitherkw) - [chainIOK](#chainiok) - [chainOptionK](#chainoptionk) + - [chainReaderK](#chainreaderk) + - [chainReaderKW](#chainreaderkw) - [chainReaderTaskEitherK](#chainreadertaskeitherk) - [chainReaderTaskEitherKW](#chainreadertaskeitherkw) + - [chainStateK](#chainstatek) - [chainTaskEitherK](#chaintaskeitherk) - [chainTaskEitherKW](#chaintaskeitherkw) - [chainTaskK](#chaintaskk) @@ -52,24 +59,22 @@ Added in v2.0.0 - [filterOrElseW](#filterorelsew) - [flap](#flap) - [flatten](#flatten) + - [flattenW](#flattenw) - [fromEitherK](#fromeitherk) - [fromIOEitherK](#fromioeitherk) - [fromIOK](#fromiok) - [fromOptionK](#fromoptionk) + - [fromReaderK](#fromreaderk) - [fromReaderTaskEitherK](#fromreadertaskeitherk) + - [fromStateK](#fromstatek) - [fromTaskEitherK](#fromtaskeitherk) - [fromTaskK](#fromtaskk) + - [local](#local) - [constructors](#constructors) - - [fromEither](#fromeither) - - [fromIO](#fromio) - - [fromIOEither](#fromioeither) - - [fromOption](#fromoption) + - [ask](#ask) + - [asks](#asks) - [fromPredicate](#frompredicate) - - [fromReaderEither](#fromreadereither) - [fromReaderTaskEither](#fromreadertaskeither) - - [fromState](#fromstate) - - [fromTask](#fromtask) - - [fromTaskEither](#fromtaskeither) - [get](#get) - [gets](#gets) - [left](#left) @@ -92,6 +97,8 @@ Added in v2.0.0 - [Chain](#chain) - [FromEither](#fromeither) - [FromIO](#fromio) + - [FromReader](#fromreader) + - [FromState](#fromstate) - [FromTask](#fromtask) - [Functor](#functor-1) - [Monad](#monad-1) @@ -105,6 +112,16 @@ Added in v2.0.0 - [~~stateReaderTaskEither~~](#statereadertaskeither) - [model](#model) - [StateReaderTaskEither (interface)](#statereadertaskeither-interface) +- [natural transformations](#natural-transformations) + - [fromEither](#fromeither) + - [fromIO](#fromio) + - [fromIOEither](#fromioeither) + - [fromOption](#fromoption) + - [fromReader](#fromreader) + - [fromReaderEither](#fromreadereither) + - [fromState](#fromstate) + - [fromTask](#fromtask) + - [fromTaskEither](#fromtaskeither) - [utils](#utils) - [apS](#aps) - [apSW](#apsw) @@ -116,6 +133,8 @@ Added in v2.0.0 - [sequenceArray](#sequencearray) - [traverseArray](#traversearray) - [traverseArrayWithIndex](#traversearraywithindex) + - [traverseReadonlyArrayWithIndex](#traversereadonlyarraywithindex) + - [traverseReadonlyNonEmptyArrayWithIndex](#traversereadonlynonemptyarraywithindex) - [~~evalState~~](#evalstate) - [~~execState~~](#execstate) - [~~run~~](#run) @@ -319,6 +338,34 @@ export declare const apSecond: ( Added in v2.0.0 +## asksStateReaderTaskEither + +Effectfully accesses the environment. + +**Signature** + +```ts +export declare const asksStateReaderTaskEither: ( + f: (r: R) => StateReaderTaskEither +) => StateReaderTaskEither +``` + +Added in v2.11.0 + +## asksStateReaderTaskEitherW + +Less strict version of [`asksStateReaderTaskEither`](#asksstatereadertaskeither). + +**Signature** + +```ts +export declare const asksStateReaderTaskEitherW: ( + f: (r1: R1) => StateReaderTaskEither +) => StateReaderTaskEither +``` + +Added in v2.11.0 + ## chainEitherK **Signature** @@ -374,6 +421,32 @@ export declare const chainFirstIOK: ( Added in v2.10.0 +## chainFirstReaderK + +**Signature** + +```ts +export declare const chainFirstReaderK: ( + f: (a: A) => R.Reader +) => (ma: StateReaderTaskEither) => StateReaderTaskEither +``` + +Added in v2.11.0 + +## chainFirstReaderKW + +Less strict version of [`chainFirstReaderK`](#chainFirstReaderK). + +**Signature** + +```ts +export declare const chainFirstReaderKW: ( + f: (a: A) => R.Reader +) => (ma: StateReaderTaskEither) => StateReaderTaskEither +``` + +Added in v2.11.0 + ## chainFirstTaskK **Signature** @@ -454,6 +527,32 @@ export declare const chainOptionK: ( Added in v2.10.0 +## chainReaderK + +**Signature** + +```ts +export declare const chainReaderK: ( + f: (a: A) => R.Reader +) => (ma: StateReaderTaskEither) => StateReaderTaskEither +``` + +Added in v2.11.0 + +## chainReaderKW + +Less strict version of [`chainReaderK`](#chainReaderK). + +**Signature** + +```ts +export declare const chainReaderKW: ( + f: (a: A) => R.Reader +) => (ma: StateReaderTaskEither) => StateReaderTaskEither +``` + +Added in v2.11.0 + ## chainReaderTaskEitherK **Signature** @@ -480,6 +579,18 @@ export declare const chainReaderTaskEitherKW: ( Added in v2.6.1 +## chainStateK + +**Signature** + +```ts +export declare const chainStateK: ( + f: (a: A) => State +) => (ma: StateReaderTaskEither) => StateReaderTaskEither +``` + +Added in v2.11.0 + ## chainTaskEitherK **Signature** @@ -527,6 +638,9 @@ export declare const filterOrElse: { (refinement: Refinement, onFalse: (a: A) => E): ( ma: StateReaderTaskEither ) => StateReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E): ( + mb: StateReaderTaskEither + ) => StateReaderTaskEither (predicate: Predicate, onFalse: (a: A) => E): ( ma: StateReaderTaskEither ) => StateReaderTaskEither @@ -546,6 +660,9 @@ export declare const filterOrElseW: { (refinement: Refinement, onFalse: (a: A) => E2): ( ma: StateReaderTaskEither ) => StateReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E2): ( + mb: StateReaderTaskEither + ) => StateReaderTaskEither (predicate: Predicate, onFalse: (a: A) => E2): ( ma: StateReaderTaskEither ) => StateReaderTaskEither @@ -582,6 +699,20 @@ export declare const flatten: ( Added in v2.0.0 +## flattenW + +Less strict version of [`flatten`](#flatten). + +**Signature** + +```ts +export declare const flattenW: ( + mma: StateReaderTaskEither> +) => StateReaderTaskEither +``` + +Added in v2.11.0 + ## fromEitherK **Signature** @@ -628,18 +759,42 @@ export declare const fromOptionK: ( Added in v2.10.0 +## fromReaderK + +**Signature** + +```ts +export declare const fromReaderK: ( + f: (...a: A) => R.Reader +) => (...a: A) => StateReaderTaskEither +``` + +Added in v2.11.0 + ## fromReaderTaskEitherK **Signature** ```ts -export declare function fromReaderTaskEitherK, B>( - f: (...a: A) => ReaderTaskEither -): (...a: A) => StateReaderTaskEither +export declare const fromReaderTaskEitherK: ( + f: (...a: A) => RTE.ReaderTaskEither +) => (...a: A) => StateReaderTaskEither ``` Added in v2.4.0 +## fromStateK + +**Signature** + +```ts +export declare const fromStateK: ( + f: (...a: A) => State +) => (...a: A) => StateReaderTaskEither +``` + +Added in v2.11.0 + ## fromTaskEitherK **Signature** @@ -664,47 +819,46 @@ export declare const fromTaskK: ( Added in v2.10.0 -# constructors +## local -## fromEither +Changes the value of the local context during the execution of the action `ma` (similar to `Contravariant`'s +`contramap`). **Signature** ```ts -export declare const fromEither: (e: E.Either) => StateReaderTaskEither +export declare const local: ( + f: (r2: R2) => R1 +) => (ma: StateReaderTaskEither) => StateReaderTaskEither ``` -Added in v2.0.0 - -## fromIO - -**Signature** +Added in v2.11.0 -```ts -export declare const fromIO: (fa: IO) => StateReaderTaskEither -``` +# constructors -Added in v2.7.0 +## ask -## fromIOEither +Reads the current context. **Signature** ```ts -export declare function fromIOEither(ma: IOEither): StateReaderTaskEither +export declare const ask: () => StateReaderTaskEither ``` -Added in v2.0.0 +Added in v2.11.0 -## fromOption +## asks + +Projects a value from the global context in a `ReaderEither`. **Signature** ```ts -export declare const fromOption: (onNone: Lazy) => (ma: Option) => StateReaderTaskEither +export declare const asks: (f: (r: R) => A) => StateReaderTaskEither ``` -Added in v2.0.0 +Added in v2.11.0 ## fromPredicate @@ -715,60 +869,19 @@ export declare const fromPredicate: { (refinement: Refinement, onFalse: (a: A) => E): ( a: A ) => StateReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => StateReaderTaskEither (predicate: Predicate, onFalse: (a: A) => E): (a: A) => StateReaderTaskEither } ``` Added in v2.4.4 -## fromReaderEither - -**Signature** - -```ts -export declare function fromReaderEither(ma: ReaderEither): StateReaderTaskEither -``` - -Added in v2.0.0 - ## fromReaderTaskEither **Signature** ```ts -export declare const fromReaderTaskEither: ( - ma: RTE.ReaderTaskEither -) => StateReaderTaskEither -``` - -Added in v2.0.0 - -## fromState - -**Signature** - -```ts -export declare const fromState: (sa: State) => StateReaderTaskEither -``` - -Added in v2.10.0 - -## fromTask - -**Signature** - -```ts -export declare const fromTask: (fa: Task) => StateReaderTaskEither -``` - -Added in v2.7.0 - -## fromTaskEither - -**Signature** - -```ts -export declare function fromTaskEither(ma: TaskEither): StateReaderTaskEither +export declare const fromReaderTaskEither: NaturalTransformation34<'ReaderTaskEither', 'StateReaderTaskEither'> ``` Added in v2.0.0 @@ -854,7 +967,7 @@ Modify the state by applying a function to the current state **Signature** ```ts -export declare const modify: (f: (s: S) => S) => StateReaderTaskEither +export declare const modify: (f: Endomorphism) => StateReaderTaskEither ``` Added in v2.0.0 @@ -993,6 +1106,26 @@ export declare const FromIO: FromIO4<'StateReaderTaskEither'> Added in v2.10.0 +## FromReader + +**Signature** + +```ts +export declare const FromReader: FromReader4<'StateReaderTaskEither'> +``` + +Added in v2.11.0 + +## FromState + +**Signature** + +```ts +export declare const FromState: FromState4<'StateReaderTaskEither'> +``` + +Added in v2.11.0 + ## FromTask **Signature** @@ -1129,6 +1262,98 @@ export interface StateReaderTaskEither { Added in v2.0.0 +# natural transformations + +## fromEither + +**Signature** + +```ts +export declare const fromEither: NaturalTransformation24<'Either', 'StateReaderTaskEither'> +``` + +Added in v2.0.0 + +## fromIO + +**Signature** + +```ts +export declare const fromIO: NaturalTransformation14<'IO', 'StateReaderTaskEither'> +``` + +Added in v2.7.0 + +## fromIOEither + +**Signature** + +```ts +export declare const fromIOEither: NaturalTransformation24<'IOEither', 'StateReaderTaskEither'> +``` + +Added in v2.0.0 + +## fromOption + +**Signature** + +```ts +export declare const fromOption: (onNone: Lazy) => NaturalTransformation14C<'Option', 'StateReaderTaskEither', E> +``` + +Added in v2.0.0 + +## fromReader + +**Signature** + +```ts +export declare const fromReader: NaturalTransformation24R<'Reader', 'StateReaderTaskEither'> +``` + +Added in v2.11.0 + +## fromReaderEither + +**Signature** + +```ts +export declare const fromReaderEither: NaturalTransformation34<'ReaderEither', 'StateReaderTaskEither'> +``` + +Added in v2.0.0 + +## fromState + +**Signature** + +```ts +export declare const fromState: NaturalTransformation24S<'State', 'StateReaderTaskEither'> +``` + +Added in v2.10.0 + +## fromTask + +**Signature** + +```ts +export declare const fromTask: NaturalTransformation14<'Task', 'StateReaderTaskEither'> +``` + +Added in v2.7.0 + +## fromTaskEither + +**Signature** + +```ts +export declare const fromTaskEither: NaturalTransformation24<'TaskEither', 'StateReaderTaskEither'> +``` + +Added in v2.0.0 + # utils ## apS @@ -1233,8 +1458,6 @@ Added in v2.8.0 ## sequenceArray -Equivalent to `ReadonlyArray#sequence(Applicative)`. - **Signature** ```ts @@ -1247,8 +1470,6 @@ Added in v2.9.0 ## traverseArray -Equivalent to `ReadonlyArray#traverse(Applicative)`. - **Signature** ```ts @@ -1261,8 +1482,6 @@ Added in v2.9.0 ## traverseArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. - **Signature** ```ts @@ -1273,6 +1492,34 @@ export declare const traverseArrayWithIndex: ( Added in v2.9.0 +## traverseReadonlyArrayWithIndex + +Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndex: ( + f: (index: number, a: A) => StateReaderTaskEither +) => (as: readonly A[]) => StateReaderTaskEither +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndex + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndex: ( + f: (index: number, a: A) => StateReaderTaskEither +) => (as: ReadonlyNonEmptyArray) => StateReaderTaskEither> +``` + +Added in v2.11.0 + ## ~~evalState~~ Use [`evaluate`](#evaluate) instead diff --git a/docs/modules/StateT.ts.md b/docs/modules/StateT.ts.md index 417bb9cb7..cff392b84 100644 --- a/docs/modules/StateT.ts.md +++ b/docs/modules/StateT.ts.md @@ -1,6 +1,6 @@ --- title: StateT.ts -nav_order: 92 +nav_order: 99 parent: Modules --- diff --git a/docs/modules/Store.ts.md b/docs/modules/Store.ts.md index 90df33d43..a8e43179b 100644 --- a/docs/modules/Store.ts.md +++ b/docs/modules/Store.ts.md @@ -1,6 +1,6 @@ --- title: Store.ts -nav_order: 93 +nav_order: 100 parent: Modules --- diff --git a/docs/modules/Strong.ts.md b/docs/modules/Strong.ts.md index 3e01b2864..c331116dd 100644 --- a/docs/modules/Strong.ts.md +++ b/docs/modules/Strong.ts.md @@ -1,6 +1,6 @@ --- title: Strong.ts -nav_order: 95 +nav_order: 102 parent: Modules --- diff --git a/docs/modules/Task.ts.md b/docs/modules/Task.ts.md index 5e78e8e03..c5553ece4 100644 --- a/docs/modules/Task.ts.md +++ b/docs/modules/Task.ts.md @@ -1,6 +1,6 @@ --- title: Task.ts -nav_order: 97 +nav_order: 104 parent: Modules --- @@ -41,8 +41,6 @@ Added in v2.0.0 - [flap](#flap) - [flatten](#flatten) - [fromIOK](#fromiok) -- [constructors](#constructors) - - [fromIO](#fromio) - [instances](#instances) - [ApplicativePar](#applicativepar) - [ApplicativeSeq](#applicativeseq) @@ -65,7 +63,10 @@ Added in v2.0.0 - [~~task~~](#task) - [model](#model) - [Task (interface)](#task-interface) +- [natural transformations](#natural-transformations) + - [fromIO](#fromio) - [utils](#utils) + - [ApT](#apt) - [Do](#do) - [apS](#aps) - [bind](#bind) @@ -75,6 +76,10 @@ Added in v2.0.0 - [sequenceSeqArray](#sequenceseqarray) - [traverseArray](#traversearray) - [traverseArrayWithIndex](#traversearraywithindex) + - [traverseReadonlyArrayWithIndex](#traversereadonlyarraywithindex) + - [traverseReadonlyArrayWithIndexSeq](#traversereadonlyarraywithindexseq) + - [traverseReadonlyNonEmptyArrayWithIndex](#traversereadonlynonemptyarraywithindex) + - [traverseReadonlyNonEmptyArrayWithIndexSeq](#traversereadonlynonemptyarraywithindexseq) - [traverseSeqArray](#traverseseqarray) - [traverseSeqArrayWithIndex](#traverseseqarraywithindex) @@ -101,7 +106,7 @@ Added in v2.0.0 **Signature** ```ts -export declare const fromTask: (fa: Task) => Task +export declare const fromTask: NaturalTransformation11<'Task', 'Task'> ``` Added in v2.7.0 @@ -281,18 +286,6 @@ export declare const fromIOK: (f: (...a: A) => IO) => (...a: A) => Task Added in v2.4.0 -# constructors - -## fromIO - -**Signature** - -```ts -export declare const fromIO: (fa: IO) => Task -``` - -Added in v2.0.0 - # instances ## ApplicativePar @@ -528,8 +521,30 @@ export interface Task { Added in v2.0.0 +# natural transformations + +## fromIO + +**Signature** + +```ts +export declare const fromIO: NaturalTransformation11<'IO', 'Task'> +``` + +Added in v2.0.0 + # utils +## ApT + +**Signature** + +```ts +export declare const ApT: Task +``` + +Added in v2.11.0 + ## Do **Signature** @@ -590,8 +605,6 @@ Added in v2.0.0 ## sequenceArray -Equivalent to `ReadonlyArray#sequence(ApplicativePar)`. - **Signature** ```ts @@ -602,8 +615,6 @@ Added in v2.9.0 ## sequenceSeqArray -Equivalent to `ReadonlyArray#sequence(ApplicativeSeq)`. - **Signature** ```ts @@ -614,8 +625,6 @@ Added in v2.9.0 ## traverseArray -Equivalent to `ReadonlyArray#traverse(ApplicativePar)`. - **Signature** ```ts @@ -626,8 +635,6 @@ Added in v2.9.0 ## traverseArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. - **Signature** ```ts @@ -638,9 +645,63 @@ export declare const traverseArrayWithIndex: ( Added in v2.9.0 -## traverseSeqArray +## traverseReadonlyArrayWithIndex -Equivalent to `ReadonlyArray#traverse(ApplicativeSeq)`. +Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndex: ( + f: (index: number, a: A) => Task +) => (as: readonly A[]) => Task +``` + +Added in v2.11.0 + +## traverseReadonlyArrayWithIndexSeq + +Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndexSeq: ( + f: (index: number, a: A) => Task +) => (as: readonly A[]) => Task +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndex + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativePar)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndex: ( + f: (index: number, a: A) => Task +) => (as: ReadonlyNonEmptyArray) => Task> +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndexSeq + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativeSeq)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndexSeq: ( + f: (index: number, a: A) => Task +) => (as: ReadonlyNonEmptyArray) => Task> +``` + +Added in v2.11.0 + +## traverseSeqArray **Signature** @@ -652,8 +713,6 @@ Added in v2.9.0 ## traverseSeqArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. - **Signature** ```ts diff --git a/docs/modules/TaskEither.ts.md b/docs/modules/TaskEither.ts.md index a42724966..4482de600 100644 --- a/docs/modules/TaskEither.ts.md +++ b/docs/modules/TaskEither.ts.md @@ -1,6 +1,6 @@ --- title: TaskEither.ts -nav_order: 98 +nav_order: 105 parent: Modules --- @@ -51,25 +51,26 @@ Added in v2.0.0 - [chainIOK](#chainiok) - [chainOptionK](#chainoptionk) - [chainTaskK](#chaintaskk) + - [chainTaskOptionK](#chaintaskoptionk) - [filterOrElse](#filterorelse) - [filterOrElseW](#filterorelsew) - [flap](#flap) - [flatten](#flatten) + - [flattenW](#flattenw) - [fromEitherK](#fromeitherk) - [fromIOEitherK](#fromioeitherk) - [fromIOK](#fromiok) - [fromOptionK](#fromoptionk) - [fromTaskK](#fromtaskk) + - [fromTaskOptionK](#fromtaskoptionk) - [orElse](#orelse) + - [orElseFirst](#orelsefirst) + - [orElseFirstW](#orelsefirstw) - [orElseW](#orelsew) + - [orLeft](#orleft) - [swap](#swap) - [constructors](#constructors) - - [fromEither](#fromeither) - - [fromIO](#fromio) - - [fromIOEither](#fromioeither) - - [fromOption](#fromoption) - [fromPredicate](#frompredicate) - - [fromTask](#fromtask) - [left](#left) - [leftIO](#leftio) - [leftTask](#lefttask) @@ -120,7 +121,15 @@ Added in v2.0.0 - [tryCatchK](#trycatchk) - [model](#model) - [TaskEither (interface)](#taskeither-interface) +- [natural transformations](#natural-transformations) + - [fromEither](#fromeither) + - [fromIO](#fromio) + - [fromIOEither](#fromioeither) + - [fromOption](#fromoption) + - [fromTask](#fromtask) + - [fromTaskOption](#fromtaskoption) - [utils](#utils) + - [ApT](#apt) - [Do](#do) - [apS](#aps) - [apSW](#apsw) @@ -133,6 +142,10 @@ Added in v2.0.0 - [taskify](#taskify) - [traverseArray](#traversearray) - [traverseArrayWithIndex](#traversearraywithindex) + - [traverseReadonlyArrayWithIndex](#traversereadonlyarraywithindex) + - [traverseReadonlyArrayWithIndexSeq](#traversereadonlyarraywithindexseq) + - [traverseReadonlyNonEmptyArrayWithIndex](#traversereadonlynonemptyarraywithindex) + - [traverseReadonlyNonEmptyArrayWithIndexSeq](#traversereadonlynonemptyarraywithindexseq) - [traverseSeqArray](#traverseseqarray) - [traverseSeqArrayWithIndex](#traverseseqarraywithindex) @@ -489,6 +502,18 @@ export declare const chainTaskK: (f: (a: A) => T.Task) => (first: Ta Added in v2.10.0 +## chainTaskOptionK + +**Signature** + +```ts +export declare const chainTaskOptionK: ( + onNone: Lazy +) => (f: (a: A) => TaskOption) => (ma: TaskEither) => TaskEither +``` + +Added in v2.11.0 + ## filterOrElse **Signature** @@ -496,6 +521,7 @@ Added in v2.10.0 ```ts export declare const filterOrElse: { (refinement: Refinement, onFalse: (a: A) => E): (ma: TaskEither) => TaskEither + (predicate: Predicate, onFalse: (a: A) => E): (mb: TaskEither) => TaskEither (predicate: Predicate, onFalse: (a: A) => E): (ma: TaskEither) => TaskEither } ``` @@ -513,6 +539,9 @@ export declare const filterOrElseW: { (refinement: Refinement, onFalse: (a: A) => E2): ( ma: TaskEither ) => TaskEither + (predicate: Predicate, onFalse: (a: A) => E2): ( + mb: TaskEither + ) => TaskEither (predicate: Predicate, onFalse: (a: A) => E2): (ma: TaskEither) => TaskEither } ``` @@ -543,6 +572,18 @@ export declare const flatten: (mma: TaskEither>) => Ta Added in v2.0.0 +## flattenW + +Less strict version of [`flatten`](#flatten). + +**Signature** + +```ts +export declare const flattenW: (mma: TaskEither>) => TaskEither +``` + +Added in v2.11.0 + ## fromEitherK **Signature** @@ -599,6 +640,18 @@ export declare const fromTaskK: (f: (...a: A) => T.Task) => (...a: A Added in v2.10.0 +## fromTaskOptionK + +**Signature** + +```ts +export declare const fromTaskOptionK: ( + onNone: Lazy +) => (f: (...a: A) => TaskOption) => (...a: A) => TaskEither +``` + +Added in v2.11.0 + ## orElse Returns `ma` if is a `Right` or the value returned by `onLeft` otherwise. @@ -631,71 +684,65 @@ test() Added in v2.0.0 -## orElseW - -Less strict version of [`orElse`](#orelse). +## orElseFirst **Signature** ```ts -export declare const orElseW: ( - onLeft: (e: E1) => TaskEither -) => (ma: TaskEither) => TaskEither +export declare const orElseFirst: ( + onLeft: (e: E) => TaskEither +) => (ma: TaskEither) => TaskEither ``` -Added in v2.10.0 +Added in v2.11.0 -## swap +## orElseFirstW **Signature** ```ts -export declare const swap: (ma: TaskEither) => TaskEither +export declare const orElseFirstW: ( + onLeft: (e: E1) => TaskEither +) => (ma: TaskEither) => TaskEither ``` -Added in v2.0.0 +Added in v2.11.0 -# constructors +## orElseW -## fromEither +Less strict version of [`orElse`](#orelse). **Signature** ```ts -export declare const fromEither: (e: E.Either) => TaskEither +export declare const orElseW: ( + onLeft: (e: E1) => TaskEither +) => (ma: TaskEither) => TaskEither ``` -Added in v2.0.0 +Added in v2.10.0 -## fromIO +## orLeft **Signature** ```ts -export declare const fromIO: (fa: IO) => TaskEither +export declare const orLeft: (onLeft: (e: E1) => T.Task) => (fa: TaskEither) => TaskEither ``` -Added in v2.7.0 +Added in v2.11.0 -## fromIOEither +## swap **Signature** ```ts -export declare const fromIOEither: (fa: IOEither) => TaskEither +export declare const swap: (ma: TaskEither) => TaskEither ``` Added in v2.0.0 -## fromOption - -**Signature** - -```ts -export declare const fromOption: (onNone: Lazy) => (ma: Option) => TaskEither -``` - -Added in v2.0.0 +# constructors ## fromPredicate @@ -704,22 +751,13 @@ Added in v2.0.0 ```ts export declare const fromPredicate: { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => TaskEither + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => TaskEither (predicate: Predicate, onFalse: (a: A) => E): (a: A) => TaskEither } ``` Added in v2.0.0 -## fromTask - -**Signature** - -```ts -export declare const fromTask: (fa: T.Task) => TaskEither -``` - -Added in v2.7.0 - ## left **Signature** @@ -1260,8 +1298,80 @@ export interface TaskEither extends Task> {} Added in v2.0.0 +# natural transformations + +## fromEither + +**Signature** + +```ts +export declare const fromEither: NaturalTransformation22<'Either', 'TaskEither'> +``` + +Added in v2.0.0 + +## fromIO + +**Signature** + +```ts +export declare const fromIO: NaturalTransformation12<'IO', 'TaskEither'> +``` + +Added in v2.7.0 + +## fromIOEither + +**Signature** + +```ts +export declare const fromIOEither: NaturalTransformation22<'IOEither', 'TaskEither'> +``` + +Added in v2.0.0 + +## fromOption + +**Signature** + +```ts +export declare const fromOption: (onNone: Lazy) => NaturalTransformation12C<'Option', 'TaskEither', E> +``` + +Added in v2.0.0 + +## fromTask + +**Signature** + +```ts +export declare const fromTask: NaturalTransformation12<'Task', 'TaskEither'> +``` + +Added in v2.7.0 + +## fromTaskOption + +**Signature** + +```ts +export declare const fromTaskOption: (onNone: Lazy) => NaturalTransformation12C<'TaskOption', 'TaskEither', E> +``` + +Added in v2.11.0 + # utils +## ApT + +**Signature** + +```ts +export declare const ApT: TaskEither +``` + +Added in v2.11.0 + ## Do **Signature** @@ -1355,8 +1465,6 @@ Added in v2.0.0 ## sequenceArray -Equivalent to `ReadonlyArray#sequence(ApplicativePar)`. - **Signature** ```ts @@ -1367,8 +1475,6 @@ Added in v2.9.0 ## sequenceSeqArray -Equivalent to `ReadonlyArray#sequence(ApplicativeSeq)`. - **Signature** ```ts @@ -1431,8 +1537,6 @@ Added in v2.0.0 ## traverseArray -Equivalent to `ReadonlyArray#traverse(ApplicativePar)`. - **Signature** ```ts @@ -1445,8 +1549,6 @@ Added in v2.9.0 ## traverseArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. - **Signature** ```ts @@ -1457,9 +1559,63 @@ export declare const traverseArrayWithIndex: ( Added in v2.9.0 -## traverseSeqArray +## traverseReadonlyArrayWithIndex + +Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndex: ( + f: (index: number, a: A) => TaskEither +) => (as: readonly A[]) => TaskEither +``` + +Added in v2.11.0 + +## traverseReadonlyArrayWithIndexSeq + +Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndexSeq: ( + f: (index: number, a: A) => TaskEither +) => (as: readonly A[]) => TaskEither +``` -Equivalent to `ReadonlyArray#traverse(ApplicativeSeq)`. +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndex + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativePar)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndex: ( + f: (index: number, a: A) => TaskEither +) => (as: ReadonlyNonEmptyArray) => TaskEither> +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndexSeq + +Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndexSeq: ( + f: (index: number, a: A) => TaskEither +) => (as: ReadonlyNonEmptyArray) => TaskEither> +``` + +Added in v2.11.0 + +## traverseSeqArray **Signature** @@ -1473,8 +1629,6 @@ Added in v2.9.0 ## traverseSeqArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. - **Signature** ```ts diff --git a/docs/modules/TaskOption.ts.md b/docs/modules/TaskOption.ts.md index d9dd4ac4a..738f0a35b 100644 --- a/docs/modules/TaskOption.ts.md +++ b/docs/modules/TaskOption.ts.md @@ -1,6 +1,6 @@ --- title: TaskOption.ts -nav_order: 99 +nav_order: 106 parent: Modules --- @@ -15,8 +15,6 @@ Added in v2.10.0 - [Alt](#alt) - [alt](#alt) - [altW](#altw) -- [Alternative](#alternative) - - [zero](#zero) - [Apply](#apply) - [ap](#ap) - [Compactable](#compactable) @@ -33,6 +31,8 @@ Added in v2.10.0 - [chain](#chain) - [Pointed](#pointed) - [of](#of) +- [Zero](#zero) + - [zero](#zero) - [combinators](#combinators) - [apFirst](#apfirst) - [apSecond](#apsecond) @@ -48,11 +48,8 @@ Added in v2.10.0 - [fromOptionK](#fromoptionk) - [fromTaskK](#fromtaskk) - [constructors](#constructors) - - [fromEither](#fromeither) - - [fromIO](#fromio) - - [fromOption](#fromoption) - [fromPredicate](#frompredicate) - - [fromTask](#fromtask) + - [guard](#guard) - [none](#none) - [some](#some) - [destructors](#destructors) @@ -66,7 +63,7 @@ Added in v2.10.0 - [matchW](#matchw) - [instances](#instances) - [Alt](#alt-1) - - [Alternative](#alternative-1) + - [Alternative](#alternative) - [ApplicativePar](#applicativepar) - [ApplicativeSeq](#applicativeseq) - [ApplyPar](#applypar) @@ -74,6 +71,7 @@ Added in v2.10.0 - [Chain](#chain) - [Compactable](#compactable-1) - [Filterable](#filterable-1) + - [FromEither](#fromeither) - [FromIO](#fromio) - [FromTask](#fromtask) - [Functor](#functor-1) @@ -82,6 +80,7 @@ Added in v2.10.0 - [MonadTask](#monadtask) - [Pointed](#pointed-1) - [URI (type alias)](#uri-type-alias) + - [Zero](#zero-1) - [interop](#interop) - [chainNullableK](#chainnullablek) - [fromNullable](#fromnullable) @@ -90,7 +89,14 @@ Added in v2.10.0 - [tryCatchK](#trycatchk) - [model](#model) - [TaskOption (interface)](#taskoption-interface) +- [natural transformations](#natural-transformations) + - [fromEither](#fromeither) + - [fromIO](#fromio) + - [fromOption](#fromoption) + - [fromTask](#fromtask) + - [fromTaskEither](#fromtaskeither) - [utils](#utils) + - [ApT](#apt) - [Do](#do) - [apS](#aps) - [bind](#bind) @@ -99,6 +105,10 @@ Added in v2.10.0 - [sequenceSeqArray](#sequenceseqarray) - [traverseArray](#traversearray) - [traverseArrayWithIndex](#traversearraywithindex) + - [traverseReadonlyArrayWithIndex](#traversereadonlyarraywithindex) + - [traverseReadonlyArrayWithIndexSeq](#traversereadonlyarraywithindexseq) + - [traverseReadonlyNonEmptyArrayWithIndex](#traversereadonlynonemptyarraywithindex) + - [traverseReadonlyNonEmptyArrayWithIndexSeq](#traversereadonlynonemptyarraywithindexseq) - [traverseSeqArray](#traverseseqarray) - [traverseSeqArrayWithIndex](#traverseseqarraywithindex) @@ -128,18 +138,6 @@ export declare const altW: (second: Lazy>) => (first: TaskOp Added in v2.10.0 -# Alternative - -## zero - -**Signature** - -```ts -export declare const zero: () => TaskOption -``` - -Added in v2.10.0 - # Apply ## ap @@ -181,7 +179,11 @@ Added in v2.10.0 **Signature** ```ts -export declare const filter: (predicate: Predicate) => (fga: TaskOption) => TaskOption +export declare const filter: { + (refinement: Refinement): (fb: TaskOption) => TaskOption + (predicate: Predicate): (fb: TaskOption) => TaskOption + (predicate: Predicate): (fa: TaskOption) => TaskOption +} ``` Added in v2.10.0 @@ -201,9 +203,11 @@ Added in v2.10.0 **Signature** ```ts -export declare const partition: ( - predicate: Predicate -) => (fga: TaskOption) => Separated, TaskOption> +export declare const partition: { + (refinement: Refinement): (fb: TaskOption) => Separated, TaskOption> + (predicate: Predicate): (fb: TaskOption) => Separated, TaskOption> + (predicate: Predicate): (fa: TaskOption) => Separated, TaskOption> +} ``` Added in v2.10.0 @@ -259,6 +263,18 @@ export declare const of: (a: A) => TaskOption Added in v2.10.0 +# Zero + +## zero + +**Signature** + +```ts +export declare const zero: () => TaskOption +``` + +Added in v2.10.0 + # combinators ## apFirst @@ -412,36 +428,6 @@ Added in v2.10.0 # constructors -## fromEither - -**Signature** - -```ts -export declare const fromEither: (e: Either) => TaskOption -``` - -Added in v2.10.0 - -## fromIO - -**Signature** - -```ts -export declare const fromIO: (fa: IO) => TaskOption -``` - -Added in v2.10.0 - -## fromOption - -**Signature** - -```ts -export declare const fromOption: (ma: O.Option) => TaskOption -``` - -Added in v2.10.0 - ## fromPredicate **Signature** @@ -449,21 +435,22 @@ Added in v2.10.0 ```ts export declare const fromPredicate: { (refinement: Refinement): (a: A) => TaskOption + (predicate: Predicate): (b: B) => TaskOption (predicate: Predicate): (a: A) => TaskOption } ``` Added in v2.10.0 -## fromTask +## guard **Signature** ```ts -export declare const fromTask: (fa: T.Task) => TaskOption +export declare const guard: (b: boolean) => TaskOption ``` -Added in v2.10.0 +Added in v2.11.0 ## none @@ -681,6 +668,16 @@ export declare const Filterable: Filterable1<'TaskOption'> Added in v2.10.0 +## FromEither + +**Signature** + +```ts +export declare const FromEither: FromEither1<'TaskOption'> +``` + +Added in v2.11.0 + ## FromIO **Signature** @@ -761,6 +758,16 @@ export type URI = typeof URI Added in v2.10.0 +## Zero + +**Signature** + +```ts +export declare const Zero: Zero1<'TaskOption'> +``` + +Added in v2.11.0 + # interop ## chainNullableK @@ -839,8 +846,70 @@ export interface TaskOption extends Task> {} Added in v2.10.0 +# natural transformations + +## fromEither + +**Signature** + +```ts +export declare const fromEither: NaturalTransformation21<'Either', 'TaskOption'> +``` + +Added in v2.10.0 + +## fromIO + +**Signature** + +```ts +export declare const fromIO: NaturalTransformation11<'IO', 'TaskOption'> +``` + +Added in v2.10.0 + +## fromOption + +**Signature** + +```ts +export declare const fromOption: NaturalTransformation11<'Option', 'TaskOption'> +``` + +Added in v2.10.0 + +## fromTask + +**Signature** + +```ts +export declare const fromTask: NaturalTransformation11<'Task', 'TaskOption'> +``` + +Added in v2.10.0 + +## fromTaskEither + +**Signature** + +```ts +export declare const fromTaskEither: NaturalTransformation21<'TaskEither', 'TaskOption'> +``` + +Added in v2.11.0 + # utils +## ApT + +**Signature** + +```ts +export declare const ApT: TaskOption +``` + +Added in v2.11.0 + ## Do **Signature** @@ -889,8 +958,6 @@ Added in v2.10.0 ## sequenceArray -Equivalent to `ReadonlyArray#sequence(ApplicativePar)`. - **Signature** ```ts @@ -901,8 +968,6 @@ Added in v2.10.0 ## sequenceSeqArray -Equivalent to `ReadonlyArray#sequence(ApplicativeSeq)`. - **Signature** ```ts @@ -913,8 +978,6 @@ Added in v2.10.0 ## traverseArray -Equivalent to `ReadonlyArray#traverse(ApplicativePar)`. - **Signature** ```ts @@ -925,8 +988,6 @@ Added in v2.10.0 ## traverseArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. - **Signature** ```ts @@ -937,9 +998,63 @@ export declare const traverseArrayWithIndex: ( Added in v2.10.0 -## traverseSeqArray +## traverseReadonlyArrayWithIndex + +Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndex: ( + f: (index: number, a: A) => TaskOption +) => (as: readonly A[]) => TaskOption +``` + +Added in v2.11.0 + +## traverseReadonlyArrayWithIndexSeq + +Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndexSeq: ( + f: (index: number, a: A) => TaskOption +) => (as: readonly A[]) => TaskOption +``` -Equivalent to `ReadonlyArray#traverse(ApplicativeSeq)`. +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndex + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativePar)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndex: ( + f: (index: number, a: A) => TaskOption +) => (as: ReadonlyNonEmptyArray) => TaskOption> +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndexSeq + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativeSeq)`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndexSeq: ( + f: (index: number, a: A) => TaskOption +) => (as: ReadonlyNonEmptyArray) => TaskOption> +``` + +Added in v2.11.0 + +## traverseSeqArray **Signature** @@ -953,8 +1068,6 @@ Added in v2.10.0 ## traverseSeqArrayWithIndex -Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. - **Signature** ```ts diff --git a/docs/modules/TaskThese.ts.md b/docs/modules/TaskThese.ts.md index 6f048e755..44f336bf4 100644 --- a/docs/modules/TaskThese.ts.md +++ b/docs/modules/TaskThese.ts.md @@ -1,6 +1,6 @@ --- title: TaskThese.ts -nav_order: 100 +nav_order: 107 parent: Modules --- @@ -24,15 +24,11 @@ Added in v2.4.0 - [fromIOK](#fromiok) - [fromOptionK](#fromoptionk) - [fromTaskK](#fromtaskk) + - [fromTheseK](#fromthesek) - [swap](#swap) - [constructors](#constructors) - [both](#both) - - [fromEither](#fromeither) - - [fromIO](#fromio) - - [fromIOEither](#fromioeither) - - [fromOption](#fromoption) - [fromPredicate](#frompredicate) - - [fromTask](#fromtask) - [left](#left) - [leftIO](#leftio) - [leftTask](#lefttask) @@ -51,6 +47,7 @@ Added in v2.4.0 - [FromEither](#fromeither) - [FromIO](#fromio) - [FromTask](#fromtask) + - [FromThese](#fromthese) - [Functor](#functor-1) - [Pointed](#pointed-1) - [URI](#uri) @@ -65,8 +62,20 @@ Added in v2.4.0 - [~~taskThese~~](#taskthese) - [model](#model) - [TaskThese (interface)](#taskthese-interface) +- [natural transformations](#natural-transformations) + - [fromEither](#fromeither) + - [fromIO](#fromio) + - [fromIOEither](#fromioeither) + - [fromOption](#fromoption) + - [fromTask](#fromtask) + - [fromThese](#fromthese) - [utils](#utils) + - [ApT](#apt) - [toTuple2](#totuple2) + - [traverseReadonlyArrayWithIndex](#traversereadonlyarraywithindex) + - [traverseReadonlyArrayWithIndexSeq](#traversereadonlyarraywithindexseq) + - [traverseReadonlyNonEmptyArrayWithIndex](#traversereadonlynonemptyarraywithindex) + - [traverseReadonlyNonEmptyArrayWithIndexSeq](#traversereadonlynonemptyarraywithindexseq) - [~~toTuple~~](#totuple) --- @@ -170,68 +179,38 @@ export declare const fromTaskK: (f: (...a: A) => T.Task) => (...a: A Added in v2.10.0 -## swap +## fromTheseK **Signature** ```ts -export declare const swap: (fa: TaskThese) => TaskThese +export declare const fromTheseK: (f: (...a: A) => TH.These) => (...a: A) => TaskThese ``` -Added in v2.4.0 - -# constructors +Added in v2.11.0 -## both +## swap **Signature** ```ts -export declare const both: (e: E, a: A) => TaskThese +export declare const swap: (fa: TaskThese) => TaskThese ``` Added in v2.4.0 -## fromEither - -**Signature** - -```ts -export declare const fromEither: (e: Either) => TaskThese -``` - -Added in v2.10.0 - -## fromIO - -**Signature** - -```ts -export declare const fromIO: (fa: IO) => TaskThese -``` - -Added in v2.7.0 +# constructors -## fromIOEither +## both **Signature** ```ts -export declare const fromIOEither: (fa: IOEither) => TaskThese +export declare const both: (e: E, a: A) => TaskThese ``` Added in v2.4.0 -## fromOption - -**Signature** - -```ts -export declare const fromOption: (onNone: Lazy) => (ma: Option) => TaskThese -``` - -Added in v2.10.0 - ## fromPredicate **Signature** @@ -239,22 +218,13 @@ Added in v2.10.0 ```ts export declare const fromPredicate: { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => TaskThese + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => TaskThese (predicate: Predicate, onFalse: (a: A) => E): (a: A) => TaskThese } ``` Added in v2.10.0 -## fromTask - -**Signature** - -```ts -export declare const fromTask: (fa: T.Task) => TaskThese -``` - -Added in v2.7.0 - ## left **Signature** @@ -451,6 +421,16 @@ export declare const FromTask: FromTask2<'TaskThese'> Added in v2.10.0 +## FromThese + +**Signature** + +```ts +export declare const FromThese: FromThese2<'TaskThese'> +``` + +Added in v2.11.0 + ## Functor **Signature** @@ -591,8 +571,80 @@ export interface TaskThese extends Task> {} Added in v2.4.0 +# natural transformations + +## fromEither + +**Signature** + +```ts +export declare const fromEither: NaturalTransformation22<'Either', 'TaskThese'> +``` + +Added in v2.10.0 + +## fromIO + +**Signature** + +```ts +export declare const fromIO: NaturalTransformation12<'IO', 'TaskThese'> +``` + +Added in v2.7.0 + +## fromIOEither + +**Signature** + +```ts +export declare const fromIOEither: NaturalTransformation22<'IOEither', 'TaskThese'> +``` + +Added in v2.4.0 + +## fromOption + +**Signature** + +```ts +export declare const fromOption: (onNone: Lazy) => NaturalTransformation12C<'Option', 'TaskThese', E> +``` + +Added in v2.10.0 + +## fromTask + +**Signature** + +```ts +export declare const fromTask: NaturalTransformation12<'Task', 'TaskThese'> +``` + +Added in v2.7.0 + +## fromThese + +**Signature** + +```ts +export declare const fromThese: NaturalTransformation22<'These', 'TaskThese'> +``` + +Added in v2.11.0 + # utils +## ApT + +**Signature** + +```ts +export declare const ApT: TaskThese +``` + +Added in v2.11.0 + ## toTuple2 **Signature** @@ -603,6 +655,66 @@ export declare const toTuple2: (e: Lazy, a: Lazy) => (fa: TaskThese< Added in v2.10.0 +## traverseReadonlyArrayWithIndex + +Equivalent to `ReadonlyArray#traverseWithIndex(getApplicative(T.ApplicativePar, S))`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndex: ( + S: Semigroup +) => (f: (index: number, a: A) => TaskThese) => (as: readonly A[]) => TaskThese +``` + +Added in v2.11.0 + +## traverseReadonlyArrayWithIndexSeq + +Equivalent to `ReadonlyArray#traverseWithIndex(getApplicative(T.ApplicativeSeq, S))`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndexSeq: ( + S: Semigroup +) => (f: (index: number, a: A) => TaskThese) => (as: readonly A[]) => TaskThese +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndex + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(getApplicative(T.ApplicativePar, S))`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndex: ( + S: Semigroup +) => ( + f: (index: number, a: A) => TaskThese +) => (as: ReadonlyNonEmptyArray) => TaskThese> +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndexSeq + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(getApplicative(T.ApplicativeSeq, S))`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndexSeq: ( + S: Semigroup +) => ( + f: (index: number, a: A) => TaskThese +) => (as: ReadonlyNonEmptyArray) => TaskThese> +``` + +Added in v2.11.0 + ## ~~toTuple~~ Use [`toTuple2`](#totuple2) instead. diff --git a/docs/modules/These.ts.md b/docs/modules/These.ts.md index a014741c8..7c8773eb1 100644 --- a/docs/modules/These.ts.md +++ b/docs/modules/These.ts.md @@ -1,6 +1,6 @@ --- title: These.ts -nav_order: 101 +nav_order: 108 parent: Modules --- @@ -47,7 +47,6 @@ Added in v2.0.0 - [swap](#swap) - [constructors](#constructors) - [both](#both) - - [fromOption](#fromoption) - [fromOptions](#fromoptions) - [left](#left) - [leftOrBoth](#leftorboth) @@ -62,14 +61,11 @@ Added in v2.0.0 - [getRightOnly](#getrightonly) - [match](#match) - [matchW](#matchw) -- [guards](#guards) - - [isBoth](#isboth) - - [isLeft](#isleft) - - [isRight](#isright) - [instances](#instances) - [Bifunctor](#bifunctor-1) - [Foldable](#foldable-1) - [FromEither](#fromeither) + - [FromThese](#fromthese) - [Functor](#functor-1) - [Pointed](#pointed-1) - [Traversable](#traversable) @@ -86,10 +82,21 @@ Added in v2.0.0 - [model](#model) - [Both (interface)](#both-interface) - [These (type alias)](#these-type-alias) +- [natural transformations](#natural-transformations) + - [fromOption](#fromoption) +- [refinements](#refinements) + - [isBoth](#isboth) + - [isLeft](#isleft) + - [isRight](#isright) - [utils](#utils) + - [ApT](#apt) + - [elem](#elem) + - [exists](#exists) - [sequence](#sequence) - [toTuple2](#totuple2) - [traverse](#traverse) + - [traverseReadonlyArrayWithIndex](#traversereadonlyarraywithindex) + - [traverseReadonlyNonEmptyArrayWithIndex](#traversereadonlynonemptyarraywithindex) - [~~toTuple~~](#totuple) --- @@ -225,16 +232,6 @@ export declare function both(left: E, right: A): These Added in v2.0.0 -## fromOption - -**Signature** - -```ts -export declare const fromOption: (onNone: Lazy) => (ma: Option) => These -``` - -Added in v2.10.0 - ## fromOptions Takes a pair of `Option`s and attempts to create a `These` from them @@ -242,7 +239,7 @@ Takes a pair of `Option`s and attempts to create a `These` from them **Signature** ```ts -export declare function fromOptions(fe: Option, fa: Option): Option> +export declare const fromOptions: (fe: Option, fa: Option) => Option> ``` **Example** @@ -475,44 +472,6 @@ export declare const matchW: ( Added in v2.10.0 -# guards - -## isBoth - -Returns `true` if the these is an instance of `Both`, `false` otherwise - -**Signature** - -```ts -export declare function isBoth(fa: These): fa is Both -``` - -Added in v2.0.0 - -## isLeft - -Returns `true` if the these is an instance of `Left`, `false` otherwise - -**Signature** - -```ts -export declare function isLeft(fa: These): fa is Left -``` - -Added in v2.0.0 - -## isRight - -Returns `true` if the these is an instance of `Right`, `false` otherwise - -**Signature** - -```ts -export declare function isRight(fa: These): fa is Right -``` - -Added in v2.0.0 - # instances ## Bifunctor @@ -545,6 +504,16 @@ export declare const FromEither: FromEither2<'These'> Added in v2.10.0 +## FromThese + +**Signature** + +```ts +export declare const FromThese: FromThese2<'These'> +``` + +Added in v2.11.0 + ## Functor **Signature** @@ -703,8 +672,88 @@ export type These = Either | Both Added in v2.0.0 +# natural transformations + +## fromOption + +**Signature** + +```ts +export declare const fromOption: (onNone: Lazy) => NaturalTransformation12C<'Option', 'These', E> +``` + +Added in v2.10.0 + +# refinements + +## isBoth + +Returns `true` if the these is an instance of `Both`, `false` otherwise + +**Signature** + +```ts +export declare function isBoth(fa: These): fa is Both +``` + +Added in v2.0.0 + +## isLeft + +Returns `true` if the these is an instance of `Left`, `false` otherwise + +**Signature** + +```ts +export declare const isLeft: (fa: These) => fa is Left +``` + +Added in v2.0.0 + +## isRight + +Returns `true` if the these is an instance of `Right`, `false` otherwise + +**Signature** + +```ts +export declare const isRight: (fa: These) => fa is Right +``` + +Added in v2.0.0 + # utils +## ApT + +**Signature** + +```ts +export declare const ApT: These +``` + +Added in v2.11.0 + +## elem + +**Signature** + +```ts +export declare const elem: (E: Eq) => (a: A) => (ma: These) => boolean +``` + +Added in v2.11.0 + +## exists + +**Signature** + +```ts +export declare const exists: (predicate: Predicate) => (ma: These) => boolean +``` + +Added in v2.11.0 + ## sequence **Signature** @@ -763,6 +812,36 @@ export declare const traverse: PipeableTraverse2<'These'> Added in v2.6.3 +## traverseReadonlyArrayWithIndex + +Equivalent to `ReadonlyArray#traverseWithIndex(getApplicative(S))`. + +**Signature** + +```ts +export declare const traverseReadonlyArrayWithIndex: ( + S: Semigroup +) => (f: (index: number, a: A) => These) => (as: readonly A[]) => These +``` + +Added in v2.11.0 + +## traverseReadonlyNonEmptyArrayWithIndex + +Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(getApplicative(S))`. + +**Signature** + +```ts +export declare const traverseReadonlyNonEmptyArrayWithIndex: ( + S: Semigroup +) => ( + f: (index: number, a: A) => These +) => (as: ReadonlyNonEmptyArray) => These> +``` + +Added in v2.11.0 + ## ~~toTuple~~ Use [`toTuple2`](#totuple2) instead. diff --git a/docs/modules/TheseT.ts.md b/docs/modules/TheseT.ts.md index dbeeacdda..b4d5191da 100644 --- a/docs/modules/TheseT.ts.md +++ b/docs/modules/TheseT.ts.md @@ -1,6 +1,6 @@ --- title: TheseT.ts -nav_order: 102 +nav_order: 109 parent: Modules --- diff --git a/docs/modules/Traced.ts.md b/docs/modules/Traced.ts.md index d2634b7d5..a05b493b2 100644 --- a/docs/modules/Traced.ts.md +++ b/docs/modules/Traced.ts.md @@ -1,6 +1,6 @@ --- title: Traced.ts -nav_order: 103 +nav_order: 110 parent: Modules --- diff --git a/docs/modules/Traversable.ts.md b/docs/modules/Traversable.ts.md index edf98b240..2eb144792 100644 --- a/docs/modules/Traversable.ts.md +++ b/docs/modules/Traversable.ts.md @@ -1,6 +1,6 @@ --- title: Traversable.ts -nav_order: 104 +nav_order: 111 parent: Modules --- diff --git a/docs/modules/TraversableWithIndex.ts.md b/docs/modules/TraversableWithIndex.ts.md index 53011ff6a..ca3c5efa8 100644 --- a/docs/modules/TraversableWithIndex.ts.md +++ b/docs/modules/TraversableWithIndex.ts.md @@ -1,6 +1,6 @@ --- title: TraversableWithIndex.ts -nav_order: 105 +nav_order: 112 parent: Modules --- diff --git a/docs/modules/Tree.ts.md b/docs/modules/Tree.ts.md index c39c0edf9..1a2459384 100644 --- a/docs/modules/Tree.ts.md +++ b/docs/modules/Tree.ts.md @@ -1,6 +1,6 @@ --- title: Tree.ts -nav_order: 106 +nav_order: 113 parent: Modules --- @@ -75,6 +75,7 @@ Added in v2.0.0 - [drawForest](#drawforest) - [drawTree](#drawtree) - [elem](#elem) + - [exists](#exists) - [sequence](#sequence) - [traverse](#traverse) @@ -680,6 +681,16 @@ export declare function elem(E: Eq): (a: A, fa: Tree) => boolean Added in v2.0.0 +## exists + +**Signature** + +```ts +export declare const exists: (predicate: Predicate) => (ma: Tree) => boolean +``` + +Added in v2.11.0 + ## sequence **Signature** diff --git a/docs/modules/Tuple.ts.md b/docs/modules/Tuple.ts.md index c978e2174..90d4eb8a1 100644 --- a/docs/modules/Tuple.ts.md +++ b/docs/modules/Tuple.ts.md @@ -1,6 +1,6 @@ --- title: Tuple.ts -nav_order: 107 +nav_order: 114 parent: Modules --- diff --git a/docs/modules/Unfoldable.ts.md b/docs/modules/Unfoldable.ts.md index 0673a6ad5..5f87adc14 100644 --- a/docs/modules/Unfoldable.ts.md +++ b/docs/modules/Unfoldable.ts.md @@ -1,6 +1,6 @@ --- title: Unfoldable.ts -nav_order: 108 +nav_order: 115 parent: Modules --- diff --git a/docs/modules/ValidationT.ts.md b/docs/modules/ValidationT.ts.md index 370f3f5d1..4214f5ea6 100644 --- a/docs/modules/ValidationT.ts.md +++ b/docs/modules/ValidationT.ts.md @@ -1,6 +1,6 @@ --- title: ValidationT.ts -nav_order: 109 +nav_order: 116 parent: Modules --- diff --git a/docs/modules/Witherable.ts.md b/docs/modules/Witherable.ts.md index f2934ae74..fa116092d 100644 --- a/docs/modules/Witherable.ts.md +++ b/docs/modules/Witherable.ts.md @@ -1,6 +1,6 @@ --- title: Witherable.ts -nav_order: 110 +nav_order: 118 parent: Modules --- @@ -16,6 +16,9 @@ Added in v2.0.0

Table of contents

+- [defaults](#defaults) + - [wiltDefault](#wiltdefault) + - [witherDefault](#witherdefault) - [type classes](#type-classes) - [Witherable (interface)](#witherable-interface) - [Witherable1 (interface)](#witherable1-interface) @@ -23,6 +26,7 @@ Added in v2.0.0 - [Witherable2C (interface)](#witherable2c-interface) - [Witherable3 (interface)](#witherable3-interface) - [utils](#utils) + - [FilterE1 (interface)](#filtere1-interface) - [PipeableWilt (interface)](#pipeablewilt-interface) - [PipeableWilt1 (interface)](#pipeablewilt1-interface) - [PipeableWilt2 (interface)](#pipeablewilt2-interface) @@ -43,9 +47,54 @@ Added in v2.0.0 - [Wither2 (interface)](#wither2-interface) - [Wither2C (interface)](#wither2c-interface) - [Wither3 (interface)](#wither3-interface) + - [filterE](#filtere) --- +# defaults + +## wiltDefault + +Return a `wilt` implementation from `Traversable` and `Compactable`. + +**Signature** + +```ts +export declare function wiltDefault( + T: Traversable2C, + C: Compactable2 +): Witherable2C['wilt'] +export declare function wiltDefault( + T: Traversable2, + C: Compactable2C +): Witherable2C['wilt'] +export declare function wiltDefault(T: Traversable1, C: Compactable1): Witherable1['wilt'] +export declare function wiltDefault(T: Traversable, C: Compactable): Witherable['wilt'] +``` + +Added in v2.11.0 + +## witherDefault + +Return a `wither` implementation from `Traversable` and `Compactable`. + +**Signature** + +```ts +export declare function witherDefault( + T: Traversable2C, + C: Compactable2 +): Witherable2C['wither'] +export declare function witherDefault( + T: Traversable2, + C: Compactable2C +): Witherable2C['wither'] +export declare function witherDefault(T: Traversable1, C: Compactable1): Witherable1['wither'] +export declare function witherDefault(T: Traversable, C: Compactable): Witherable['wither'] +``` + +Added in v2.11.0 + # type classes ## Witherable (interface) @@ -122,6 +171,33 @@ Added in v2.0.0 # utils +## FilterE1 (interface) + +**Signature** + +```ts +export interface FilterE1 { + (F: Applicative3): ( + predicate: (a: A) => Kind3 + ) => (ga: Kind) => Kind3> + (F: Applicative3C): ( + predicate: (a: A) => Kind3 + ) => (ga: Kind) => Kind3> + (F: Applicative2): ( + predicate: (a: A) => Kind2 + ) => (ga: Kind) => Kind2> + (F: Applicative2C):
( + predicate: (a: A) => Kind2 + ) => (ga: Kind) => Kind2> + (F: Applicative1): ( + predicate: (a: A) => Kind + ) => (ga: Kind) => Kind> + (F: Applicative): (predicate: (a: A) => HKT) => (ga: Kind) => HKT> +} +``` + +Added in v2.11.0 + ## PipeableWilt (interface) **Signature** @@ -691,3 +767,20 @@ export interface Wither3 { ``` Added in v2.0.0 + +## filterE + +Filter values inside a `F` context. + +See `ReadonlyArray`'s `filterE` for an example of usage. + +**Signature** + +```ts +export declare function filterE(W: Witherable1): FilterE1 +export declare function filterE( + W: Witherable +): (F: Applicative) => (predicate: (a: A) => HKT) => (ga: HKT) => HKT> +``` + +Added in v2.11.0 diff --git a/docs/modules/Writer.ts.md b/docs/modules/Writer.ts.md index 76569fdb7..892b9657f 100644 --- a/docs/modules/Writer.ts.md +++ b/docs/modules/Writer.ts.md @@ -1,6 +1,6 @@ --- title: Writer.ts -nav_order: 111 +nav_order: 119 parent: Modules --- diff --git a/docs/modules/WriterT.ts.md b/docs/modules/WriterT.ts.md index e9ff3cf29..5f9e57f0e 100644 --- a/docs/modules/WriterT.ts.md +++ b/docs/modules/WriterT.ts.md @@ -1,6 +1,6 @@ --- title: WriterT.ts -nav_order: 112 +nav_order: 120 parent: Modules --- diff --git a/docs/modules/Zero.ts.md b/docs/modules/Zero.ts.md new file mode 100644 index 000000000..a218ad433 --- /dev/null +++ b/docs/modules/Zero.ts.md @@ -0,0 +1,148 @@ +--- +title: Zero.ts +nav_order: 121 +parent: Modules +--- + +## Zero overview + +Added in v2.11.0 + +--- + +

Table of contents

+ +- [constructors](#constructors) + - [guard](#guard) +- [type classes](#type-classes) + - [Zero (interface)](#zero-interface) + - [Zero1 (interface)](#zero1-interface) + - [Zero2 (interface)](#zero2-interface) + - [Zero2C (interface)](#zero2c-interface) + - [Zero3 (interface)](#zero3-interface) + - [Zero3C (interface)](#zero3c-interface) + - [Zero4 (interface)](#zero4-interface) + +--- + +# constructors + +## guard + +**Signature** + +```ts +export declare function guard( + F: Zero4, + P: Pointed4 +): (b: boolean) => Kind4 +export declare function guard(F: Zero3, P: Pointed3): (b: boolean) => Kind3 +export declare function guard( + F: Zero3C, + P: Pointed3C +): (b: boolean) => Kind3 +export declare function guard(F: Zero2, P: Pointed2): (b: boolean) => Kind2 +export declare function guard( + F: Zero2C, + P: Pointed2C +): (b: boolean) => Kind2 +export declare function guard(F: Zero1, P: Pointed1): (b: boolean) => Kind +export declare function guard(F: Zero, P: Pointed): (b: boolean) => HKT +``` + +Added in v2.11.0 + +# type classes + +## Zero (interface) + +**Signature** + +```ts +export interface Zero { + readonly URI: F + readonly zero:
() => HKT +} +``` + +Added in v2.11.0 + +## Zero1 (interface) + +**Signature** + +```ts +export interface Zero1 { + readonly URI: F + readonly zero: () => Kind +} +``` + +Added in v2.11.0 + +## Zero2 (interface) + +**Signature** + +```ts +export interface Zero2 { + readonly URI: F + readonly zero: () => Kind2 +} +``` + +Added in v2.11.0 + +## Zero2C (interface) + +**Signature** + +```ts +export interface Zero2C { + readonly URI: F + readonly _E: E + readonly zero: () => Kind2 +} +``` + +Added in v2.11.0 + +## Zero3 (interface) + +**Signature** + +```ts +export interface Zero3 { + readonly URI: F + readonly zero: () => Kind3 +} +``` + +Added in v2.11.0 + +## Zero3C (interface) + +**Signature** + +```ts +export interface Zero3C { + readonly URI: F + readonly _E: E + readonly zero: () => Kind3 +} +``` + +Added in v2.11.0 + +## Zero4 (interface) + +**Signature** + +```ts +export interface Zero4 { + readonly URI: F + readonly zero: () => Kind4 +} +``` + +Added in v2.11.0 diff --git a/docs/modules/boolean.ts.md b/docs/modules/boolean.ts.md index af55cd2c4..8d6d59d59 100644 --- a/docs/modules/boolean.ts.md +++ b/docs/modules/boolean.ts.md @@ -26,6 +26,8 @@ Added in v2.2.0 - [SemigroupAll](#semigroupall) - [SemigroupAny](#semigroupany) - [Show](#show) +- [refinements](#refinements) + - [isBoolean](#isboolean) --- @@ -233,3 +235,15 @@ export declare const Show: S.Show ``` Added in v2.10.0 + +# refinements + +## isBoolean + +**Signature** + +```ts +export declare const isBoolean: Refinement +``` + +Added in v2.11.0 diff --git a/docs/modules/function.ts.md b/docs/modules/function.ts.md index 90672c5f7..6a72a3f40 100644 --- a/docs/modules/function.ts.md +++ b/docs/modules/function.ts.md @@ -1,6 +1,6 @@ --- title: function.ts -nav_order: 37 +nav_order: 41 parent: Modules --- @@ -14,18 +14,17 @@ Added in v2.0.0 - [instances](#instances) - [getBooleanAlgebra](#getbooleanalgebra) - - [getEndomorphismMonoid](#getendomorphismmonoid) - [getMonoid](#getmonoid) - [getRing](#getring) - [getSemigroup](#getsemigroup) - [getSemiring](#getsemiring) + - [~~getEndomorphismMonoid~~](#getendomorphismmonoid) - [utils](#utils) - - [Endomorphism (interface)](#endomorphism-interface) - [FunctionN (interface)](#functionn-interface) - [Lazy (interface)](#lazy-interface) - - [Predicate (interface)](#predicate-interface) - - [Refinement (interface)](#refinement-interface) + - [SK](#sk) - [absurd](#absurd) + - [apply](#apply) - [constFalse](#constfalse) - [constNull](#constnull) - [constTrue](#consttrue) @@ -38,12 +37,15 @@ Added in v2.0.0 - [hole](#hole) - [identity](#identity) - [increment](#increment) - - [not](#not) - [pipe](#pipe) - [tuple](#tuple) - [tupled](#tupled) - [unsafeCoerce](#unsafecoerce) - [untupled](#untupled) + - [~~Endomorphism~~ (interface)](#endomorphism-interface) + - [~~Predicate~~ (interface)](#predicate-interface) + - [~~Refinement~~ (interface)](#refinement-interface) + - [~~not~~](#not) --- @@ -59,18 +61,6 @@ export declare const getBooleanAlgebra: (B: BooleanAlgebra) => Added in v2.10.0 -## getEndomorphismMonoid - -Endomorphism form a monoid where the `empty` value is the identity function. - -**Signature** - -```ts -export declare const getEndomorphismMonoid: () => Monoid> -``` - -Added in v2.10.0 - ## getMonoid Unary functions form a monoid as long as you can provide a monoid for the codomain. @@ -84,7 +74,8 @@ export declare const getMonoid: (M: Monoid) => () => Monoid<(a: **Example** ```ts -import { Predicate, getMonoid } from 'fp-ts/function' +import { Predicate } from 'fp-ts/Predicate' +import { getMonoid } from 'fp-ts/function' import * as B from 'fp-ts/boolean' const f: Predicate = (n) => n <= 2 @@ -155,19 +146,19 @@ export declare const getSemiring: (S: Semiring) => Semiring<(a: A) => B Added in v2.10.0 -# utils +## ~~getEndomorphismMonoid~~ -## Endomorphism (interface) +Use `Endomorphism` module instead. **Signature** ```ts -export interface Endomorphism { - (a: A): A -} +export declare const getEndomorphismMonoid: () => Monoid> ``` -Added in v2.0.0 +Added in v2.10.0 + +# utils ## FunctionN (interface) @@ -203,39 +194,35 @@ export interface Lazy { Added in v2.0.0 -## Predicate (interface) +## SK **Signature** ```ts -export interface Predicate { - (a: A): boolean -} +export declare const SK: (_: A, b: B) => B ``` -Added in v2.0.0 +Added in v2.11.0 -## Refinement (interface) +## absurd **Signature** ```ts -export interface Refinement { - (a: A): a is B -} +export declare function absurd(_: never): A ``` Added in v2.0.0 -## absurd +## apply **Signature** ```ts -export declare function absurd(_: never): A +export declare const apply: (a: A) => (f: (a: A) => B) => B ``` -Added in v2.0.0 +Added in v2.11.0 ## constFalse @@ -448,16 +435,6 @@ export declare function increment(n: number): number Added in v2.0.0 -## not - -**Signature** - -```ts -export declare function not(predicate: Predicate): Predicate -``` - -Added in v2.0.0 - ## pipe Pipes the value of an expression into a pipeline of functions. @@ -769,3 +746,57 @@ export declare function untupled, B>(f: (a: A) ``` Added in v2.4.0 + +## ~~Endomorphism~~ (interface) + +Use `Endomorphism` module instead. + +**Signature** + +```ts +export interface Endomorphism { + (a: A): A +} +``` + +Added in v2.0.0 + +## ~~Predicate~~ (interface) + +Use `Predicate` module instead. + +**Signature** + +```ts +export interface Predicate { + (a: A): boolean +} +``` + +Added in v2.0.0 + +## ~~Refinement~~ (interface) + +Use `Refinement` module instead. + +**Signature** + +```ts +export interface Refinement { + (a: A): a is B +} +``` + +Added in v2.0.0 + +## ~~not~~ + +Use `Predicate` module instead. + +**Signature** + +```ts +export declare function not(predicate: Predicate): Predicate +``` + +Added in v2.0.0 diff --git a/docs/modules/index.ts.md b/docs/modules/index.ts.md index ac9dc8a58..3dcca3664 100644 --- a/docs/modules/index.ts.md +++ b/docs/modules/index.ts.md @@ -1,6 +1,6 @@ --- title: index.ts -nav_order: 44 +nav_order: 48 parent: Modules --- @@ -39,6 +39,7 @@ Added in v2.0.0 - [distributiveLattice](#distributivelattice) - [either](#either) - [eitherT](#eithert) + - [endomorphism](#endomorphism) - [eq](#eq) - [extend](#extend) - [field](#field) @@ -48,7 +49,10 @@ Added in v2.0.0 - [foldableWithIndex](#foldablewithindex) - [fromEither](#fromeither) - [fromIO](#fromio) + - [fromReader](#fromreader) + - [fromState](#fromstate) - [fromTask](#fromtask) + - [fromThese](#fromthese) - [function](#function) - [functor](#functor) - [functorWithIndex](#functorwithindex) @@ -71,6 +75,7 @@ Added in v2.0.0 - [monadTask](#monadtask) - [monadThrow](#monadthrow) - [monoid](#monoid) + - [naturalTransformation](#naturaltransformation) - [nonEmptyArray](#nonemptyarray) - [number](#number) - [option](#option) @@ -79,6 +84,7 @@ Added in v2.0.0 - [ordering](#ordering) - [pipeable](#pipeable) - [pointed](#pointed) + - [predicate](#predicate) - [profunctor](#profunctor) - [random](#random) - [reader](#reader) @@ -93,6 +99,7 @@ Added in v2.0.0 - [readonlySet](#readonlyset) - [readonlyTuple](#readonlytuple) - [record](#record) + - [refinement](#refinement) - [ring](#ring) - [semigroup](#semigroup) - [semigroupoid](#semigroupoid) @@ -120,9 +127,11 @@ Added in v2.0.0 - [tuple](#tuple) - [unfoldable](#unfoldable) - [validationT](#validationt) + - [void](#void) - [witherable](#witherable) - [writer](#writer) - [writerT](#writert) + - [zero](#zero) --- @@ -388,6 +397,16 @@ export declare const eitherT: typeof eitherT Added in v2.0.0 +## endomorphism + +**Signature** + +```ts +export declare const endomorphism: typeof endomorphism +``` + +Added in v2.11.0 + ## eq **Signature** @@ -478,6 +497,26 @@ export declare const fromIO: typeof fromIO Added in v2.10.0 +## fromReader + +**Signature** + +```ts +export declare const fromReader: typeof fromReader +``` + +Added in v2.11.0 + +## fromState + +**Signature** + +```ts +export declare const fromState: typeof fromState +``` + +Added in v2.11.0 + ## fromTask **Signature** @@ -488,6 +527,16 @@ export declare const fromTask: typeof fromTask Added in v2.10.0 +## fromThese + +**Signature** + +```ts +export declare const fromThese: typeof fromThese +``` + +Added in v2.11.0 + ## function **Signature** @@ -708,6 +757,16 @@ export declare const monoid: typeof monoid Added in v2.0.0 +## naturalTransformation + +**Signature** + +```ts +export declare const naturalTransformation: typeof naturalTransformation +``` + +Added in v2.11.0 + ## nonEmptyArray **Signature** @@ -788,6 +847,16 @@ export declare const pointed: typeof pointed Added in v2.10.0 +## predicate + +**Signature** + +```ts +export declare const predicate: typeof predicate +``` + +Added in v2.11.0 + ## profunctor **Signature** @@ -928,6 +997,16 @@ export declare const record: typeof record Added in v2.0.0 +## refinement + +**Signature** + +```ts +export declare const refinement: typeof refinement +``` + +Added in v2.11.0 + ## ring **Signature** @@ -1198,6 +1277,16 @@ export declare const validationT: typeof validationT Added in v2.0.0 +## void + +**Signature** + +```ts +export declare const void: typeof void_ +``` + +Added in v2.11.0 + ## witherable **Signature** @@ -1227,3 +1316,13 @@ export declare const writerT: typeof writerT ``` Added in v2.4.0 + +## zero + +**Signature** + +```ts +export declare const zero: typeof zero +``` + +Added in v2.11.0 diff --git a/docs/modules/internal.ts.md b/docs/modules/internal.ts.md index ebc7bbb05..ffa8a1ade 100644 --- a/docs/modules/internal.ts.md +++ b/docs/modules/internal.ts.md @@ -1,6 +1,6 @@ --- title: internal.ts -nav_order: 45 +nav_order: 49 parent: Modules --- diff --git a/docs/modules/number.ts.md b/docs/modules/number.ts.md index 28902f1e8..bef10770a 100644 --- a/docs/modules/number.ts.md +++ b/docs/modules/number.ts.md @@ -1,6 +1,6 @@ --- title: number.ts -nav_order: 62 +nav_order: 67 parent: Modules --- @@ -16,12 +16,15 @@ Added in v2.10.0 - [Bounded](#bounded) - [Eq](#eq) - [Field](#field) + - [MagmaSub](#magmasub) - [MonoidProduct](#monoidproduct) - [MonoidSum](#monoidsum) - [Ord](#ord) - [SemigroupProduct](#semigroupproduct) - [SemigroupSum](#semigroupsum) - [Show](#show) +- [refinements](#refinements) + - [isNumber](#isnumber) --- @@ -57,6 +60,16 @@ export declare const Field: F.Field Added in v2.10.0 +## MagmaSub + +**Signature** + +```ts +export declare const MagmaSub: Magma +``` + +Added in v2.11.0 + ## MonoidProduct `number` monoid under multiplication. @@ -160,3 +173,15 @@ export declare const Show: S.Show ``` Added in v2.10.0 + +# refinements + +## isNumber + +**Signature** + +```ts +export declare const isNumber: Refinement +``` + +Added in v2.11.0 diff --git a/docs/modules/pipeable.ts.md b/docs/modules/pipeable.ts.md index 4d3646173..9b726e944 100644 --- a/docs/modules/pipeable.ts.md +++ b/docs/modules/pipeable.ts.md @@ -1,6 +1,6 @@ --- title: pipeable.ts -nav_order: 67 +nav_order: 72 parent: Modules --- diff --git a/docs/modules/string.ts.md b/docs/modules/string.ts.md index 0447861e1..dab82a8ae 100644 --- a/docs/modules/string.ts.md +++ b/docs/modules/string.ts.md @@ -1,6 +1,6 @@ --- title: string.ts -nav_order: 94 +nav_order: 101 parent: Modules --- @@ -12,19 +12,168 @@ Added in v2.10.0

Table of contents

+- [combinators](#combinators) + - [replace](#replace) + - [slice](#slice) + - [toLowerCase](#tolowercase) + - [toUpperCase](#touppercase) + - [trim](#trim) + - [trimLeft](#trimleft) + - [trimRight](#trimright) - [instances](#instances) - [Eq](#eq) - [Monoid](#monoid) - [Ord](#ord) - [Semigroup](#semigroup) - [Show](#show) +- [refinements](#refinements) + - [isString](#isstring) - [utils](#utils) - [empty](#empty) + - [endsWith](#endswith) + - [includes](#includes) - [isEmpty](#isempty) - [size](#size) + - [split](#split) + - [startsWith](#startswith) --- +# combinators + +## replace + +**Signature** + +```ts +export declare const replace: (searchValue: string | RegExp, replaceValue: string) => (s: string) => string +``` + +**Example** + +```ts +import * as S from 'fp-ts/string' +import { pipe } from 'fp-ts/function' + +assert.deepStrictEqual(pipe('abc', S.replace('b', 'd')), 'adc') +``` + +Added in v2.11.0 + +## slice + +**Signature** + +```ts +export declare const slice: (start: number, end: number) => (s: string) => string +``` + +**Example** + +```ts +import * as S from 'fp-ts/string' +import { pipe } from 'fp-ts/function' + +assert.deepStrictEqual(pipe('abcd', S.slice(1, 3)), 'bc') +``` + +Added in v2.11.0 + +## toLowerCase + +**Signature** + +```ts +export declare const toLowerCase: (s: string) => string +``` + +**Example** + +```ts +import * as S from 'fp-ts/string' +import { pipe } from 'fp-ts/function' + +assert.deepStrictEqual(pipe('A', S.toLowerCase), 'a') +``` + +Added in v2.11.0 + +## toUpperCase + +**Signature** + +```ts +export declare const toUpperCase: (s: string) => string +``` + +**Example** + +```ts +import * as S from 'fp-ts/string' +import { pipe } from 'fp-ts/function' + +assert.deepStrictEqual(pipe('a', S.toUpperCase), 'A') +``` + +Added in v2.11.0 + +## trim + +**Signature** + +```ts +export declare const trim: (s: string) => string +``` + +**Example** + +```ts +import * as S from 'fp-ts/string' +import { pipe } from 'fp-ts/function' + +assert.deepStrictEqual(pipe(' a ', S.trim), 'a') +``` + +Added in v2.11.0 + +## trimLeft + +**Signature** + +```ts +export declare const trimLeft: (s: string) => string +``` + +**Example** + +```ts +import * as S from 'fp-ts/string' +import { pipe } from 'fp-ts/function' + +assert.deepStrictEqual(pipe(' a ', S.trimLeft), 'a ') +``` + +Added in v2.11.0 + +## trimRight + +**Signature** + +```ts +export declare const trimRight: (s: string) => string +``` + +**Example** + +```ts +import * as S from 'fp-ts/string' +import { pipe } from 'fp-ts/function' + +assert.deepStrictEqual(pipe(' a ', S.trimRight), ' a') +``` + +Added in v2.11.0 + # instances ## Eq @@ -35,6 +184,15 @@ Added in v2.10.0 export declare const Eq: E.Eq ``` +**Example** + +```ts +import * as S from 'fp-ts/string' + +assert.deepStrictEqual(S.Eq.equals('a', 'a'), true) +assert.deepStrictEqual(S.Eq.equals('a', 'b'), false) +``` + Added in v2.10.0 ## Monoid @@ -55,6 +213,7 @@ export declare const Monoid: M.Monoid import * as S from 'fp-ts/string' assert.deepStrictEqual(S.Monoid.concat('a', 'b'), 'ab') +assert.deepStrictEqual(S.Monoid.concat('a', S.Monoid.empty), 'a') ``` Added in v2.10.0 @@ -67,6 +226,16 @@ Added in v2.10.0 export declare const Ord: O.Ord ``` +**Example** + +```ts +import * as S from 'fp-ts/string' + +assert.deepStrictEqual(S.Ord.compare('a', 'a'), 0) +assert.deepStrictEqual(S.Ord.compare('a', 'b'), -1) +assert.deepStrictEqual(S.Ord.compare('b', 'a'), 1) +``` + Added in v2.10.0 ## Semigroup @@ -97,8 +266,37 @@ Added in v2.10.0 export declare const Show: Sh.Show ``` +**Example** + +```ts +import * as S from 'fp-ts/string' + +assert.deepStrictEqual(S.Show.show('a'), '"a"') +``` + Added in v2.10.0 +# refinements + +## isString + +**Signature** + +```ts +export declare const isString: Refinement +``` + +**Example** + +```ts +import * as S from 'fp-ts/string' + +assert.deepStrictEqual(S.isString('a'), true) +assert.deepStrictEqual(S.isString(1), false) +``` + +Added in v2.11.0 + # utils ## empty @@ -113,6 +311,46 @@ export declare const empty: string Added in v2.10.0 +## endsWith + +**Signature** + +```ts +export declare const endsWith: (searchString: string, position?: number | undefined) => (s: string) => boolean +``` + +**Example** + +```ts +import * as S from 'fp-ts/string' +import { pipe } from 'fp-ts/function' + +assert.deepStrictEqual(pipe('abc', S.endsWith('c')), true) +assert.deepStrictEqual(pipe('ab', S.endsWith('c')), false) +``` + +Added in v2.11.0 + +## includes + +**Signature** + +```ts +export declare const includes: (searchString: string, position?: number | undefined) => (s: string) => boolean +``` + +**Example** + +```ts +import * as S from 'fp-ts/string' +import { pipe } from 'fp-ts/function' + +assert.deepStrictEqual(pipe('abc', S.includes('b')), true) +assert.deepStrictEqual(pipe('abc', S.includes('d')), false) +``` + +Added in v2.11.0 + ## isEmpty Test whether a `string` is empty. @@ -123,6 +361,16 @@ Test whether a `string` is empty. export declare const isEmpty: (s: string) => boolean ``` +**Example** + +```ts +import * as S from 'fp-ts/string' +import { pipe } from 'fp-ts/function' + +assert.deepStrictEqual(pipe('', S.isEmpty), true) +assert.deepStrictEqual(pipe('a', S.isEmpty), false) +``` + Added in v2.10.0 ## size @@ -135,4 +383,53 @@ Calculate the number of characters in a `string`. export declare const size: (s: string) => number ``` +**Example** + +```ts +import * as S from 'fp-ts/string' +import { pipe } from 'fp-ts/function' + +assert.deepStrictEqual(pipe('abc', S.size), 3) +``` + Added in v2.10.0 + +## split + +**Signature** + +```ts +export declare const split: (separator: string | RegExp) => (s: string) => ReadonlyNonEmptyArray +``` + +**Example** + +```ts +import * as S from 'fp-ts/string' +import { pipe } from 'fp-ts/function' + +assert.deepStrictEqual(pipe('abc', S.split('')), ['a', 'b', 'c']) +assert.deepStrictEqual(pipe('', S.split('')), ['']) +``` + +Added in v2.11.0 + +## startsWith + +**Signature** + +```ts +export declare const startsWith: (searchString: string, position?: number | undefined) => (s: string) => boolean +``` + +**Example** + +```ts +import * as S from 'fp-ts/string' +import { pipe } from 'fp-ts/function' + +assert.deepStrictEqual(pipe('abc', S.startsWith('a')), true) +assert.deepStrictEqual(pipe('bc', S.startsWith('a')), false) +``` + +Added in v2.11.0 diff --git a/docs/modules/struct.ts.md b/docs/modules/struct.ts.md index 87660a046..a85036956 100644 --- a/docs/modules/struct.ts.md +++ b/docs/modules/struct.ts.md @@ -1,6 +1,6 @@ --- title: struct.ts -nav_order: 96 +nav_order: 103 parent: Modules --- @@ -14,6 +14,8 @@ Added in v2.10.0 - [instances](#instances) - [getAssignSemigroup](#getassignsemigroup) +- [utils](#utils) + - [evolve](#evolve) --- @@ -44,3 +46,37 @@ assert.deepStrictEqual(S.concat({ name: 'name', age: 23 }, { name: 'name', age: ``` Added in v2.10.0 + +# utils + +## evolve + +Creates a new object by recursively evolving a shallow copy of `a`, according to the `transformation` functions. + +**Signature** + +```ts +export declare const evolve: unknown }>( + transformations: F +) => (a: A) => { [K in keyof F]: ReturnType } +``` + +**Example** + +```ts +import { pipe } from 'fp-ts/function' +import { evolve } from 'fp-ts/struct' + +assert.deepStrictEqual( + pipe( + { a: 'a', b: 1 }, + evolve({ + a: (a) => a.length, + b: (b) => b * 2, + }) + ), + { a: 1, b: 2 } +) +``` + +Added in v2.11.0 diff --git a/docs/modules/void.ts.md b/docs/modules/void.ts.md new file mode 100644 index 000000000..9e6bcb394 --- /dev/null +++ b/docs/modules/void.ts.md @@ -0,0 +1,41 @@ +--- +title: void.ts +nav_order: 117 +parent: Modules +--- + +## void overview + +Added in v2.11.0 + +--- + +

Table of contents

+ +- [instances](#instances) + - [Monoid](#monoid) + - [Semigroup](#semigroup) + +--- + +# instances + +## Monoid + +**Signature** + +```ts +export declare const Monoid: M.Monoid +``` + +Added in v2.11.0 + +## Semigroup + +**Signature** + +```ts +export declare const Semigroup: Se.Semigroup +``` + +Added in v2.11.0 diff --git a/dtslint/ts3.5/Array.ts b/dtslint/ts3.5/Array.ts index 273e3694d..5187b755f 100644 --- a/dtslint/ts3.5/Array.ts +++ b/dtslint/ts3.5/Array.ts @@ -9,6 +9,16 @@ declare const ns: Array declare const ss: Array declare const tns: Array<[number, string]> +// prepend + +pipe(ss, _.prepend('a')) // $ExpectType NonEmptyArray +pipe(ss, _.prependW(1)) // $ExpectType NonEmptyArray + +// append + +pipe(ss, _.append('a')) // $ExpectType NonEmptyArray +pipe(ss, _.appendW(1)) // $ExpectType NonEmptyArray + // // zip // @@ -28,55 +38,6 @@ _.zipWith(ns, ss, (n, s) => [n, s] as const) // $ExpectType (readonly [number, s _.unzip(tns) // $ExpectType [number[], string[]] pipe(tns, _.unzip) // $ExpectType [number[], string[]] -// -// Filterable overlodings -// - -declare function isStringWithIndex(i: number, x: unknown): x is string - -_.array.filterWithIndex([] as Array, isStringWithIndex) // $ExpectType string[] -_.array.partitionWithIndex([] as Array, isStringWithIndex) // $ExpectType Separated<(string | number)[], string[]> - -// -// filter -// - -// $ExpectType number[] -pipe( - us, - _.filter((u: unknown): u is number => typeof u === 'number') -) - -// -// filterWithIndex -// - -// $ExpectType number[] -pipe( - us, - _.filterWithIndex((_, u: unknown): u is number => typeof u === 'number') -) - -// -// partition -// - -// $ExpectType Separated -pipe( - us, - _.partition((u: unknown): u is number => typeof u === 'number') -) - -// -// partitionWithIndex -// - -// $ExpectType Separated -pipe( - us, - _.partitionWithIndex((_, u: unknown): u is number => typeof u === 'number') -) - // // spanLeft // @@ -189,3 +150,149 @@ pipe( identity ) ) + +// ------------------------------------------------------------------------------------- +// Predicate-based APIs +// ------------------------------------------------------------------------------------- + +declare const prns: Array +declare const prsns: Array +declare const isString: (u: unknown) => u is string +declare const isNumber: (sn: string | number) => sn is number +declare const predicate: (sn: string | number) => boolean +declare const isStringWithIndex: (i: number, u: unknown) => u is string +declare const isNumberWithIndex: (i: number, sn: string | number) => sn is number +declare const predicateWithIndex: (i: number, sn: string | number) => boolean + +// +// filter +// + +// $ExpectType string[] +pipe(prsns, _.filter(isString)) +// $ExpectType number[] +pipe(prns, _.filter(predicate)) +// $ExpectType number[] +pipe( + prns, + _.filter( + ( + x // $ExpectType number + ) => true + ) +) + +// +// filterWithIndex +// + +// $ExpectType string[] +pipe(prsns, _.filterWithIndex(isStringWithIndex)) +// $ExpectType number[] +pipe(prns, _.filterWithIndex(predicateWithIndex)) +// $ExpectType number[] +pipe( + prns, + _.filterWithIndex( + ( + i, // $ExpectType number + x // $ExpectType number + ) => true + ) +) + +// +// partition +// + +// $ExpectType Separated +pipe(prsns, _.partition(isString)) +// $ExpectType Separated +pipe(prns, _.partition(predicate)) +// $ExpectType Separated<(string | number)[], number[]> +pipe(prsns, _.partition(isNumber)) +// $ExpectType Separated +pipe( + prns, + _.partition( + ( + x // $ExpectType number + ) => true + ) +) + +// +// partitionWithIndex +// + +// $ExpectType Separated +pipe(prsns, _.partitionWithIndex(isStringWithIndex)) +// $ExpectType Separated +pipe(prns, _.partitionWithIndex(predicateWithIndex)) +// $ExpectType Separated<(string | number)[], number[]> +pipe(prsns, _.partitionWithIndex(isNumberWithIndex)) +// $ExpectType Separated +pipe( + prns, + _.partitionWithIndex( + ( + i, // $ExpectType number + x // $ExpectType number + ) => true + ) +) + +// +// takeLeftWhile +// + +// $ExpectType string[] +pipe(prsns, _.takeLeftWhile(isString)) +// $ExpectType number[] +pipe(prns, _.takeLeftWhile(predicate)) + +// +// dropLeftWhile +// + +// $ExpectType string[] +pipe(prsns, _.dropLeftWhile(isString)) +// $ExpectType number[] +pipe(prns, _.dropLeftWhile(predicate)) + +// +// spanLeft +// + +// $ExpectType Spanned +pipe(prsns, _.spanLeft(isString)) +// $ExpectType Spanned +pipe(prns, _.spanLeft(predicate)) + +// +// findFirst +// + +// $ExpectType Option +pipe(prsns, _.findFirst(isString)) +// $ExpectType Option +pipe(prns, _.findFirst(predicate)) + +// +// findLast +// + +// $ExpectType Option +pipe(prsns, _.findLast(isString)) +// $ExpectType Option +pipe(prns, _.findLast(predicate)) + +// +// isEmpty +// + +// $ExpectType Either +pipe( + ss, + E.fromPredicate(_.isEmpty, (as) => as) +) diff --git a/dtslint/ts3.5/Either.ts b/dtslint/ts3.5/Either.ts index 6d3d9200b..c3030a634 100644 --- a/dtslint/ts3.5/Either.ts +++ b/dtslint/ts3.5/Either.ts @@ -1,6 +1,6 @@ import * as _ from '../../src/Either' import { pipe, flow, identity } from '../../src/function' -import * as B from '../../src/boolean' +import * as RA from '../../src/ReadonlyArray' // // getOrElseW @@ -34,16 +34,6 @@ declare const f: (key: K) => D[K] // $ExpectType Either flow(f, _.fromNullable('error'))('foo') -// -// Witherable overlodings -// - -declare function isString(x: unknown): x is string -const W = _.getWitherable(B.MonoidAll) - -W.filter(_.right(1), isString) // $ExpectType Either -W.partition(_.right(1), isString) // $ExpectType Separated, Either> - // // do notation // @@ -96,3 +86,71 @@ pipe( _.right('a'), _.chainFirst((s) => _.stringifyJSON(s, identity)) ) + +// ------------------------------------------------------------------------------------- +// Predicate-based APIs +// ------------------------------------------------------------------------------------- + +declare const n: number +declare const sn: string | number +declare const en: _.Either +declare const esn: _.Either +declare const isString: (u: unknown) => u is string +declare const predicate: (sn: string | number) => boolean + +// +// fromPredicate +// + +// $ExpectType Either +pipe( + sn, + _.fromPredicate(isString, () => false) +) +// $ExpectType Either +pipe( + n, + _.fromPredicate(predicate, () => false) +) +// $ExpectType Either +pipe( + n, + _.fromPredicate( + ( + n // $ExpectType number + ) => true, + () => false + ) +) + +// +// filterOrElse +// + +// $ExpectType Either +pipe( + esn, + _.filterOrElse(isString, () => false) +) +// $ExpectType Either +pipe( + en, + _.filterOrElse(predicate, () => false) +) +// $ExpectType Either +pipe( + en, + _.filterOrElse( + ( + n // $ExpectType number + ) => true, + () => false + ) +) + +// +// exists +// + +declare const es: _.Either[] +const x = pipe(es, RA.filter(_.exists((n) => n > 0))) diff --git a/dtslint/ts3.5/IOEither.ts b/dtslint/ts3.5/IOEither.ts index 8ba6d6e91..6e4582575 100644 --- a/dtslint/ts3.5/IOEither.ts +++ b/dtslint/ts3.5/IOEither.ts @@ -13,6 +13,56 @@ pipe( _.getOrElseW(() => IO.of(null)) ) +// +// orElse +// + +// $ExpectType IOEither +pipe( + _.left('a'), + _.orElse((a) => _.left(a.length)) +) + +// +// orElseW +// + +// $ExpectType IOEither +pipe( + _.left('a'), + _.orElseW((a) => _.right(a.length)) +) + +// +// orElseFirst +// + +// $ExpectType IOEither +pipe( + _.left('a'), + _.orElseFirst((a) => _.right(a.length)) +) + +// +// orElseFirstW +// + +// $ExpectType IOEither +pipe( + _.left('a'), + _.orElseFirstW((a) => _.left(a.length)) +) + +// +// orLeft +// + +// $ExpectType IOEither +pipe( + _.left('a'), + _.orLeft((a) => IO.of(a.length)) +) + // // chainW // diff --git a/dtslint/ts3.5/Map.ts b/dtslint/ts3.5/Map.ts index faa42e17d..6df164788 100644 --- a/dtslint/ts3.5/Map.ts +++ b/dtslint/ts3.5/Map.ts @@ -1,17 +1,8 @@ import * as _ from '../../src/Map' import * as S from '../../src/string' import * as N from '../../src/number' - -// -// FilterableWithIndex overloadings -// - -const FWI = _.getFilterableWithIndex<'a' | 'b'>() - -declare function isStringWithKey(i: 'a' | 'b', x: unknown): x is string - -FWI.filterWithIndex(_.empty as Map<'a' | 'b', string | number>, isStringWithKey) // $ExpectType Map<"a" | "b", string> -FWI.partitionWithIndex(_.empty as Map<'a' | 'b', string | number>, isStringWithKey) // $ExpectType Separated, Map<"a" | "b", string>> +import { pipe } from '../../src/function' +import * as E from '../../src/Either' // // member @@ -47,3 +38,104 @@ _.lookupWithKey(S.Eq)('a') // $ExpectType
(m: Map) => Option<[stri _.isSubmap(S.Eq, N.Eq)(new Map([['a', 1]]), new Map([['a', 1]])) // $ExpectType boolean _.isSubmap(S.Eq, N.Eq)(new Map([['a', 1]])) // $ExpectType (me: Map) => boolean + +// ------------------------------------------------------------------------------------- +// Predicate-based APIs +// ------------------------------------------------------------------------------------- + +declare const prns: Map +declare const prsns: Map +declare const isString: (u: unknown) => u is string +declare const isNumber: (sn: string | number) => sn is number +declare const predicate: (sn: string | number) => boolean +declare const isStringWithIndex: (k: string, u: unknown) => u is string +declare const isNumberWithIndex: (k: string, sn: string | number) => sn is number +declare const predicateWithIndex: (k: string, sn: string | number) => boolean + +// +// filter +// + +// $ExpectType Map +pipe(prsns, _.filter(isString)) +// $ExpectType Map +pipe(prns, _.filter(predicate)) +// $ExpectType Map +pipe( + prns, + _.filter( + ( + x // $ExpectType number + ) => true + ) +) + +// +// filterWithIndex +// + +// $ExpectType Map +pipe(prsns, _.filterWithIndex(isStringWithIndex)) +// $ExpectType Map +pipe(prns, _.filterWithIndex(predicateWithIndex)) +// $ExpectType Map +pipe( + prns, + _.filterWithIndex( + ( + k, // $ExpectType string + x // $ExpectType number + ) => true + ) +) + +// +// partition +// + +// $ExpectType Separated, Map> +pipe(prsns, _.partition(isString)) +// $ExpectType Separated, Map> +pipe(prns, _.partition(predicate)) +// $ExpectType Separated, Map> +pipe(prsns, _.partition(isNumber)) +// $ExpectType Separated, Map> +pipe( + prns, + _.partition( + ( + x // $ExpectType number + ) => true + ) +) + +// +// partitionWithIndex +// + +// $ExpectType Separated, Map> +pipe(prsns, _.partitionWithIndex(isStringWithIndex)) +// $ExpectType Separated, Map> +pipe(prns, _.partitionWithIndex(predicateWithIndex)) +// $ExpectType Separated, Map> +pipe(prsns, _.partitionWithIndex(isNumberWithIndex)) +// $ExpectType Separated, Map> +pipe( + prns, + _.partitionWithIndex( + ( + k, // $ExpectType string + x // $ExpectType number + ) => true + ) +) + +// +// isEmpty +// + +// $ExpectType Either, Map> +pipe( + prns, + E.fromPredicate(_.isEmpty, (as) => as) +) diff --git a/dtslint/ts3.5/NonEmptyArray.ts b/dtslint/ts3.5/NonEmptyArray.ts index a11ce46d6..01e1baa74 100644 --- a/dtslint/ts3.5/NonEmptyArray.ts +++ b/dtslint/ts3.5/NonEmptyArray.ts @@ -2,6 +2,7 @@ import * as _ from '../../src/NonEmptyArray' import { Ord } from '../../src/Ord' import { pipe } from '../../src/function' +declare const as: Array declare const neas: _.NonEmptyArray declare const nens: _.NonEmptyArray declare const netns: _.NonEmptyArray<[number, string]> @@ -105,3 +106,12 @@ _.filter(isNumber1)(neasn) pipe(neasn, _.filter(isNumber2)) // $ExpectType Option> _.filter(isNumber2)(neasn) + +// +// concat +// + +_.concat(as, neas) // $ExpectType NonEmptyArray +_.concat(neas, as) // $ExpectType NonEmptyArray +_.concat(neas)(as) // $ExpectType NonEmptyArray +_.concat(as)(neas) // $ExpectType NonEmptyArray diff --git a/dtslint/ts3.5/Option.ts b/dtslint/ts3.5/Option.ts index 732cfd014..f53af7f58 100644 --- a/dtslint/ts3.5/Option.ts +++ b/dtslint/ts3.5/Option.ts @@ -11,21 +11,6 @@ pipe( _.getOrElseW(() => null) ) -// -// getRefinement -// - -interface A { - type: 'A' -} -interface B { - type: 'B' -} -type C = A | B - -// $ExpectError -_.getRefinement((c) => (c.type === 'B' ? _.some(c) : _.none)) - // // fromNullable // @@ -40,15 +25,6 @@ declare const f: (key: K) => D[K] // $ExpectType Option flow(f, _.fromNullable)('foo') -// -// Filterable overlodings -// - -declare function isString(x: unknown): x is string - -_.option.filter(_.some('a'), isString) // $ExpectType Option -_.option.partition(_.some('a'), isString) // $ExpectType Separated, Option> - // // Do // @@ -59,3 +35,71 @@ pipe( _.bind('a', () => _.of(1)), _.bind('b', () => _.of('b')) ) + +// ------------------------------------------------------------------------------------- +// Predicate-based APIs +// ------------------------------------------------------------------------------------- + +declare const n: number +declare const sn: string | number +declare const on: _.Option +declare const osn: _.Option +declare const isString: (u: unknown) => u is string +declare const isNumber: (sn: string | number) => sn is number +declare const predicate: (sn: string | number) => boolean + +// +// filter +// + +// $ExpectType Option +pipe(osn, _.filter(isString)) +// $ExpectType Option +pipe(on, _.filter(predicate)) +// $ExpectType Option +pipe( + on, + _.filter( + ( + x // $ExpectType number + ) => true + ) +) + +// +// partition +// + +// $ExpectType Separated, Option> +pipe(osn, _.partition(isString)) +// $ExpectType Separated, Option> +pipe(on, _.partition(predicate)) +// $ExpectType Separated, Option> +pipe(osn, _.partition(isNumber)) +// $ExpectType Separated, Option> +pipe( + on, + _.partition( + ( + x // $ExpectType number + ) => true + ) +) + +// +// fromPredicate +// + +// $ExpectType Option +pipe(sn, _.fromPredicate(isString)) +// $ExpectType Option +pipe(n, _.fromPredicate(predicate)) +// $ExpectType Option +pipe( + n, + _.fromPredicate( + ( + n // $ExpectType number + ) => true + ) +) diff --git a/dtslint/ts3.5/ReaderEither.ts b/dtslint/ts3.5/ReaderEither.ts index 16471f932..d46abdfe4 100644 --- a/dtslint/ts3.5/ReaderEither.ts +++ b/dtslint/ts3.5/ReaderEither.ts @@ -13,6 +13,56 @@ pipe( _.getOrElseW(() => R.of<{ b: number }, null>(null)) ) +// +// orElse +// + +// $ExpectType ReaderEither<{ a: string; }, number, never> +pipe( + _.left<{ a: string }, string, never>('a'), + _.orElse((a) => _.left(a.length)) +) + +// +// orElseW +// + +// $ExpectType ReaderEither<{ b: number; } & { a: string; }, never, string | number> +pipe( + _.left<{ a: string }, string, string>('a'), + _.orElseW((a) => _.right<{ b: number }, never, string | number>(a.length)) +) + +// +// orElseFirst +// + +// $ExpectType ReaderEither<{ a: string; }, string, never> +pipe( + _.left<{ a: string }, string, never>('a'), + _.orElseFirst((a) => _.right(a.length)) +) + +// +// orElseFirstW +// + +// $ExpectType ReaderEither<{ a: string; }, string | number, never> +pipe( + _.left<{ a: string }, string, never>('a'), + _.orElseFirstW((a) => _.left(a.length)) +) + +// +// orLeft +// + +// $ExpectType ReaderEither<{ a: string; }, number, never> +pipe( + _.left<{ a: string }, string, never>('a'), + _.orLeft((a) => R.of(a.length)) +) + // // chainW // diff --git a/dtslint/ts3.5/ReaderT.ts b/dtslint/ts3.5/ReaderT.ts new file mode 100644 index 000000000..13a09f6ed --- /dev/null +++ b/dtslint/ts3.5/ReaderT.ts @@ -0,0 +1,23 @@ +import * as _ from '../../src/ReaderT' +import * as TE from '../../src/TaskEither' +import * as TTH from '../../src/TaskThese' +import * as RTE from '../../src/ReaderTaskEither' +import * as SRTE from '../../src/StateReaderTaskEither' + +// $ExpectType (f: (r: R) => Either) => Reader> +_.fromNaturalTransformation(TE.fromEither) + +// $ExpectType (f: (r: R) => IO) => Reader> +_.fromNaturalTransformation(TE.fromIO) + +// $ExpectType (f: (r: R) => Reader) => Reader> +_.fromNaturalTransformation(RTE.fromReader) + +// $ExpectType (f: (r: R) => State) => Reader> +_.fromNaturalTransformation(SRTE.fromState) + +// $ExpectType (f: (r: R) => Task) => Reader> +_.fromNaturalTransformation(TE.fromTask) + +// $ExpectType (f: (r: R) => These) => Reader> +_.fromNaturalTransformation(TTH.fromThese) diff --git a/dtslint/ts3.5/ReaderTaskEither.ts b/dtslint/ts3.5/ReaderTaskEither.ts index 2d98efc4a..3c2122a10 100644 --- a/dtslint/ts3.5/ReaderTaskEither.ts +++ b/dtslint/ts3.5/ReaderTaskEither.ts @@ -15,6 +15,56 @@ pipe( _.getOrElseW(() => RT.of<{ b: number }, null>(null)) ) +// +// orElse +// + +// $ExpectType ReaderTaskEither<{ a: string; }, number, never> +pipe( + _.left<{ a: string }, string, never>('a'), + _.orElse((a) => _.left(a.length)) +) + +// +// orElseW +// + +// $ExpectType ReaderTaskEither<{ b: number; } & { a: string; }, never, string | number> +pipe( + _.left<{ a: string }, string, string>('a'), + _.orElseW((a) => _.right<{ b: number }, never, string | number>(a.length)) +) + +// +// orElseFirst +// + +// $ExpectType ReaderTaskEither<{ a: string; }, string, never> +pipe( + _.left<{ a: string }, string, never>('a'), + _.orElseFirst((a) => _.right(a.length)) +) + +// +// orElseFirstW +// + +// $ExpectType ReaderTaskEither<{ a: string; }, string | number, never> +pipe( + _.left<{ a: string }, string, never>('a'), + _.orElseFirstW((a) => _.left(a.length)) +) + +// +// orLeft +// + +// $ExpectType ReaderTaskEither<{ a: string; }, number, never> +pipe( + _.left<{ a: string }, string, never>('a'), + _.orLeft((a) => RT.of(a.length)) +) + // // chainW // diff --git a/dtslint/ts3.5/ReadonlyArray.ts b/dtslint/ts3.5/ReadonlyArray.ts index 0ed91a98e..84c57d6d2 100644 --- a/dtslint/ts3.5/ReadonlyArray.ts +++ b/dtslint/ts3.5/ReadonlyArray.ts @@ -9,6 +9,16 @@ declare const rns: ReadonlyArray declare const rss: ReadonlyArray declare const rtns: ReadonlyArray +// prepend + +pipe(rss, _.prepend('a')) // $ExpectType ReadonlyNonEmptyArray +pipe(rss, _.prependW(1)) // $ExpectType ReadonlyNonEmptyArray + +// append + +pipe(rss, _.append('a')) // $ExpectType ReadonlyNonEmptyArray +pipe(rss, _.appendW(1)) // $ExpectType ReadonlyNonEmptyArray + // // zip // @@ -28,46 +38,6 @@ _.zipWith(rns, rss, (n, s) => [n, s] as const) // $ExpectType readonly (readonly _.unzip(rtns) // $ExpectType readonly [readonly number[], readonly string[]] pipe(rtns, _.unzip) // $ExpectType readonly [readonly number[], readonly string[]] -// -// filter -// - -// $ExpectType readonly number[] -pipe( - rus, - _.filter((u: unknown): u is number => typeof u === 'number') -) - -// -// filterWithIndex -// - -// $ExpectType readonly number[] -pipe( - rus, - _.filterWithIndex((_, u: unknown): u is number => typeof u === 'number') -) - -// -// partition -// - -// $ExpectType Separated -pipe( - rus, - _.partition((u: unknown): u is number => typeof u === 'number') -) - -// -// partitionWithIndex -// - -// $ExpectType Separated -pipe( - rus, - _.partitionWithIndex((_, u: unknown): u is number => typeof u === 'number') -) - // // spanLeft // @@ -180,3 +150,178 @@ pipe( identity ) ) + +// ------------------------------------------------------------------------------------- +// Predicate-based APIs +// ------------------------------------------------------------------------------------- + +declare const prns: ReadonlyArray +declare const prsns: ReadonlyArray +declare const isString: (u: unknown) => u is string +declare const isNumber: (sn: string | number) => sn is number +declare const predicate: (sn: string | number) => boolean +declare const isStringWithIndex: (i: number, u: unknown) => u is string +declare const isNumberWithIndex: (i: number, sn: string | number) => sn is number +declare const predicateWithIndex: (i: number, sn: string | number) => boolean + +// +// filter +// + +// $ExpectType readonly string[] +pipe(prsns, _.filter(isString)) +// $ExpectType readonly number[] +pipe(prns, _.filter(predicate)) +// $ExpectType readonly number[] +pipe( + prns, + _.filter( + ( + x // $ExpectType number + ) => true + ) +) + +// #1484 +const isPositive = E.exists((n: number) => n > 0) +declare const eithers: ReadonlyArray> +pipe(eithers, _.filter(E.isRight), _.filter(isPositive)) + +interface Registered { + readonly type: 'Registered' + readonly username: string +} +interface Unregistered { + readonly type: 'Unregistered' +} + +type User = Registered | Unregistered + +declare const users: ReadonlyArray +declare const isRegistered: (u: User) => u is Registered +declare const p: (u: User) => boolean + +const registereds = _.filter(isRegistered)(users) +_.filter(p)(registereds) // $ExpectType readonly Registered[] + +interface Test { + test: string +} +declare const arrayOfTest: Test[] +const isFoo = (t: T) => t.test === 'foo' +pipe(arrayOfTest, _.filter(isFoo)) // $ExpectType readonly Test[] + +// +// filterWithIndex +// + +// $ExpectType readonly string[] +pipe(prsns, _.filterWithIndex(isStringWithIndex)) +// $ExpectType readonly number[] +pipe(prns, _.filterWithIndex(predicateWithIndex)) +// $ExpectType readonly number[] +pipe( + prns, + _.filterWithIndex( + ( + i, // $ExpectType number + x // $ExpectType number + ) => true + ) +) + +// +// partition +// + +// $ExpectType Separated +pipe(prsns, _.partition(isString)) +// $ExpectType Separated +pipe(prns, _.partition(predicate)) +// $ExpectType Separated +pipe(prsns, _.partition(isNumber)) +// $ExpectType Separated +pipe( + rns, + _.partition( + ( + x // $ExpectType number + ) => true + ) +) + +// +// partitionWithIndex +// + +// $ExpectType Separated +pipe(prsns, _.partitionWithIndex(isStringWithIndex)) +// $ExpectType Separated +pipe(prns, _.partitionWithIndex(predicateWithIndex)) +// $ExpectType Separated +pipe(prsns, _.partitionWithIndex(isNumberWithIndex)) +// $ExpectType Separated +pipe( + prns, + _.partitionWithIndex( + ( + i, // $ExpectType number + x // $ExpectType number + ) => true + ) +) + +// +// takeLeftWhile +// + +// $ExpectType readonly string[] +pipe(prsns, _.takeLeftWhile(isString)) +// $ExpectType readonly number[] +pipe(prns, _.takeLeftWhile(predicate)) + +// +// dropLeftWhile +// + +// $ExpectType readonly string[] +pipe(prsns, _.dropLeftWhile(isString)) +// $ExpectType readonly number[] +pipe(prns, _.dropLeftWhile(predicate)) + +// +// spanLeft +// + +// $ExpectType Spanned +pipe(prsns, _.spanLeft(isString)) +// $ExpectType Spanned +pipe(prns, _.spanLeft(predicate)) + +// +// findFirst +// + +// $ExpectType Option +pipe(prsns, _.findFirst(isString)) +// $ExpectType Option +pipe(prns, _.findFirst(predicate)) + +// +// findLast +// + +// $ExpectType Option +pipe(prsns, _.findLast(isString)) +// $ExpectType Option +pipe(prns, _.findLast(predicate)) + +// +// isEmpty +// + +// $ExpectType Either +pipe( + rss, + E.fromPredicate(_.isEmpty, (as) => as) +) diff --git a/dtslint/ts3.5/ReadonlyMap.ts b/dtslint/ts3.5/ReadonlyMap.ts index eb67dd032..44aec6d93 100644 --- a/dtslint/ts3.5/ReadonlyMap.ts +++ b/dtslint/ts3.5/ReadonlyMap.ts @@ -1,17 +1,8 @@ import * as _ from '../../src/ReadonlyMap' import * as N from '../../src/number' import * as S from '../../src/string' - -// -// FilterableWithIndex overloadings -// - -const FWI = _.getFilterableWithIndex<'a' | 'b'>() - -declare function isStringWithKey(i: 'a' | 'b', x: unknown): x is string - -FWI.filterWithIndex(_.empty as ReadonlyMap<'a' | 'b', string | number>, isStringWithKey) // $ExpectType ReadonlyMap<"a" | "b", string> -FWI.partitionWithIndex(_.empty as ReadonlyMap<'a' | 'b', string | number>, isStringWithKey) // $ExpectType Separated, ReadonlyMap<"a" | "b", string>> +import { pipe } from '../../src/function' +import * as E from '../../src/Either' // // member @@ -47,3 +38,104 @@ _.lookupWithKey(S.Eq)('a') // $ExpectType (m: ReadonlyMap) => Opti _.isSubmap(S.Eq, N.Eq)(new Map([['a', 1]]), new Map([['a', 1]])) // $ExpectType boolean _.isSubmap(S.Eq, N.Eq)(new Map([['a', 1]])) // $ExpectType (me: ReadonlyMap) => boolean + +// ------------------------------------------------------------------------------------- +// Predicate-based APIs +// ------------------------------------------------------------------------------------- + +declare const prns: ReadonlyMap +declare const prsns: ReadonlyMap +declare const isString: (u: unknown) => u is string +declare const isNumber: (sn: string | number) => sn is number +declare const predicate: (sn: string | number) => boolean +declare const isStringWithIndex: (k: string, u: unknown) => u is string +declare const isNumberWithIndex: (k: string, sn: string | number) => sn is number +declare const predicateWithIndex: (k: string, sn: string | number) => boolean + +// +// filter +// + +// $ExpectType ReadonlyMap +pipe(prsns, _.filter(isString)) +// $ExpectType ReadonlyMap +pipe(prns, _.filter(predicate)) +// $ExpectType ReadonlyMap +pipe( + prns, + _.filter( + ( + x // $ExpectType number + ) => true + ) +) + +// +// filterWithIndex +// + +// $ExpectType ReadonlyMap +pipe(prsns, _.filterWithIndex(isStringWithIndex)) +// $ExpectType ReadonlyMap +pipe(prns, _.filterWithIndex(predicateWithIndex)) +// $ExpectType ReadonlyMap +pipe( + prns, + _.filterWithIndex( + ( + k, // $ExpectType string + x // $ExpectType number + ) => true + ) +) + +// +// partition +// + +// $ExpectType Separated, ReadonlyMap> +pipe(prsns, _.partition(isString)) +// $ExpectType Separated, ReadonlyMap> +pipe(prns, _.partition(predicate)) +// $ExpectType Separated, ReadonlyMap> +pipe(prsns, _.partition(isNumber)) +// $ExpectType Separated, ReadonlyMap> +pipe( + prns, + _.partition( + ( + x // $ExpectType number + ) => true + ) +) + +// +// partitionWithIndex +// + +// $ExpectType Separated, ReadonlyMap> +pipe(prsns, _.partitionWithIndex(isStringWithIndex)) +// $ExpectType Separated, ReadonlyMap> +pipe(prns, _.partitionWithIndex(predicateWithIndex)) +// $ExpectType Separated, ReadonlyMap> +pipe(prsns, _.partitionWithIndex(isNumberWithIndex)) +// $ExpectType Separated, ReadonlyMap> +pipe( + prns, + _.partitionWithIndex( + ( + k, // $ExpectType string + x // $ExpectType number + ) => true + ) +) + +// +// isEmpty +// + +// $ExpectType Either, ReadonlyMap> +pipe( + prns, + E.fromPredicate(_.isEmpty, (as) => as) +) diff --git a/dtslint/ts3.5/ReadonlyNonEmptyArray.ts b/dtslint/ts3.5/ReadonlyNonEmptyArray.ts index 5748ac1b7..5586acb6b 100644 --- a/dtslint/ts3.5/ReadonlyNonEmptyArray.ts +++ b/dtslint/ts3.5/ReadonlyNonEmptyArray.ts @@ -106,3 +106,12 @@ _.filter(isNumber1)(neasn) pipe(neasn, _.filter(isNumber2)) // $ExpectType Option> _.filter(isNumber2)(neasn) + +// +// concat +// + +_.concat(ras, rneas) // $ExpectType ReadonlyNonEmptyArray +_.concat(rneas, ras) // $ExpectType ReadonlyNonEmptyArray +_.concat(rneas)(ras) // $ExpectType ReadonlyNonEmptyArray +_.concat(ras)(rneas) // $ExpectType ReadonlyNonEmptyArray diff --git a/dtslint/ts3.5/ReadonlyRecord.ts b/dtslint/ts3.5/ReadonlyRecord.ts index 86be63e9a..af43096b8 100644 --- a/dtslint/ts3.5/ReadonlyRecord.ts +++ b/dtslint/ts3.5/ReadonlyRecord.ts @@ -66,6 +66,11 @@ _.collect((_k: 'a', n: number) => n)(l1) // $ExpectType readonly number[] _.collect((_k, n: number) => n)(d1) // $ExpectType readonly number[] _.collect((_k: 'a' | 'b', n: number) => n)(r1) // $ExpectType readonly number[] +_.collect(S.Ord)((_k: 'a', n: number) => n)({ a: 1 }) // $ExpectType readonly number[] +_.collect(S.Ord)((_k: 'a', n: number) => n)(l1) // $ExpectType readonly number[] +_.collect(S.Ord)((_k, n: number) => n)(d1) // $ExpectType readonly number[] +_.collect(S.Ord)((_k: 'a' | 'b', n: number) => n)(r1) // $ExpectType readonly number[] + // // insertAt // @@ -108,12 +113,21 @@ _.map((n: number) => n > 2)(r1) // $ExpectType Readonly k)(d1) // $ExpectType string +_.reduceWithIndex(S.Ord)('', (k: 'a' | 'b', _n) => k)(r1) // $ExpectType string + _.reduceWithIndex('', (k: string, _n) => k)(d1) // $ExpectType string _.reduceWithIndex('', (k: 'a' | 'b', _n) => k)(r1) // $ExpectType string +_.foldMapWithIndex(S.Ord)(S.Monoid)((k: string, _n) => k)(d1) // $ExpectType string +_.foldMapWithIndex(S.Ord)(S.Monoid)((k: 'a' | 'b', _n) => k)(r1) // $ExpectType string + _.foldMapWithIndex(S.Monoid)((k: string, _n) => k)(d1) // $ExpectType string _.foldMapWithIndex(S.Monoid)((k: 'a' | 'b', _n) => k)(r1) // $ExpectType string +_.reduceRightWithIndex(S.Ord)('', (k: string, _n, _b) => k)(d1) // $ExpectType string +_.reduceRightWithIndex(S.Ord)('', (k: 'a' | 'b', _n, _b) => k)(r1) // $ExpectType string + _.reduceRightWithIndex('', (k: string, _n, _b) => k)(d1) // $ExpectType string _.reduceRightWithIndex('', (k: 'a' | 'b', _n, _b) => k)(r1) // $ExpectType string @@ -182,3 +196,16 @@ _.lookup('a') // $ExpectType (r: Readonly>) => Option _.elem(N.Eq)(1, recordString) // $ExpectType boolean _.elem(N.Eq)(1) // $ExpectType (fa: Readonly>) => boolean + +// +// reduce +// + +pipe( + r1, + _.reduce(1, (acc, n) => acc + n) +) +pipe( + r1, + _.reduce(S.Ord)(1, (acc, n) => acc + n) +) diff --git a/dtslint/ts3.5/ReadonlySet.ts b/dtslint/ts3.5/ReadonlySet.ts index 93f0be837..17b3e348b 100644 --- a/dtslint/ts3.5/ReadonlySet.ts +++ b/dtslint/ts3.5/ReadonlySet.ts @@ -1,5 +1,7 @@ import * as _ from '../../src/ReadonlySet' import * as N from '../../src/number' +import { pipe } from '../../src/function' +import * as E from '../../src/Either' declare const me: ReadonlySet @@ -37,3 +39,61 @@ _.intersection(N.Eq)(me) // $ExpectType (me: ReadonlySet) => ReadonlySet _.difference(N.Eq)(me, me) // $ExpectType ReadonlySet _.difference(N.Eq)(me) // $ExpectType (me: ReadonlySet) => ReadonlySet + +// ------------------------------------------------------------------------------------- +// Predicate-based APIs +// ------------------------------------------------------------------------------------- + +declare const prns: ReadonlySet +declare const prsns: ReadonlySet +declare const isString: (u: unknown) => u is string +declare const isNumber: (sn: string | number) => sn is number +declare const predicate: (sn: string | number) => boolean + +// +// filter +// + +// $ExpectType ReadonlySet +pipe(prsns, _.filter(isString)) +// $ExpectType ReadonlySet +pipe(prns, _.filter(predicate)) +// $ExpectType ReadonlySet +pipe( + prns, + _.filter( + ( + x // $ExpectType number + ) => true + ) +) + +// +// partition +// + +// $ExpectType Separated, ReadonlySet> +pipe(prsns, _.partition(isString)) +// $ExpectType Separated, ReadonlySet> +pipe(prns, _.partition(predicate)) +// $ExpectType Separated, ReadonlySet> +pipe(prsns, _.partition(isNumber)) +// $ExpectType Separated, ReadonlySet> +pipe( + prns, + _.partition( + ( + x // $ExpectType number + ) => true + ) +) + +// +// isEmpty +// + +// $ExpectType Either, ReadonlySet> +pipe( + me, + E.fromPredicate(_.isEmpty, (as) => as) +) diff --git a/dtslint/ts3.5/Record.ts b/dtslint/ts3.5/Record.ts index d3d33537c..e7933f2eb 100644 --- a/dtslint/ts3.5/Record.ts +++ b/dtslint/ts3.5/Record.ts @@ -66,6 +66,11 @@ _.collect((_k: 'a', n: number) => n)(l1) // $ExpectType number[] _.collect((_k, n: number) => n)(d1) // $ExpectType number[] _.collect((_k: 'a' | 'b', n: number) => n)(r1) // $ExpectType number[] +_.collect(S.Ord)((_k: 'a', n: number) => n)({ a: 1 }) // $ExpectType number[] +_.collect(S.Ord)((_k: 'a', n: number) => n)(l1) // $ExpectType number[] +_.collect(S.Ord)((_k, n: number) => n)(d1) // $ExpectType number[] +_.collect(S.Ord)((_k: 'a' | 'b', n: number) => n)(r1) // $ExpectType number[] + // // toArray // @@ -117,12 +122,21 @@ _.map((n: number) => n > 2)(r1) // $ExpectType Record<"a" | "b", boolean> // reduceWithIndex // +_.reduceWithIndex(S.Ord)('', (k: string, _n) => k)(d1) // $ExpectType string +_.reduceWithIndex(S.Ord)('', (k: 'a' | 'b', _n) => k)(r1) // $ExpectType string + _.reduceWithIndex('', (k: string, _n) => k)(d1) // $ExpectType string _.reduceWithIndex('', (k: 'a' | 'b', _n) => k)(r1) // $ExpectType string +_.foldMapWithIndex(S.Ord)(S.Monoid)((k: string, _n) => k)(d1) // $ExpectType string +_.foldMapWithIndex(S.Ord)(S.Monoid)((k: 'a' | 'b', _n) => k)(r1) // $ExpectType string + _.foldMapWithIndex(S.Monoid)((k: string, _n) => k)(d1) // $ExpectType string _.foldMapWithIndex(S.Monoid)((k: 'a' | 'b', _n) => k)(r1) // $ExpectType string +_.reduceRightWithIndex(S.Ord)('', (k: string, _n, _b) => k)(d1) // $ExpectType string +_.reduceRightWithIndex(S.Ord)('', (k: 'a' | 'b', _n, _b) => k)(r1) // $ExpectType string + _.reduceRightWithIndex('', (k: string, _n, _b) => k)(d1) // $ExpectType string _.reduceRightWithIndex('', (k: 'a' | 'b', _n, _b) => k)(r1) // $ExpectType string @@ -191,3 +205,16 @@ _.lookup('a') // $ExpectType (r: Record) => Option _.elem(N.Eq)(1, recordString) // $ExpectType boolean _.elem(N.Eq)(1) // $ExpectType (fa: Record) => boolean + +// +// reduce +// + +pipe( + r1, + _.reduce(1, (acc, n) => acc + n) +) +pipe( + r1, + _.reduce(S.Ord)(1, (acc, n) => acc + n) +) diff --git a/dtslint/ts3.5/Set.ts b/dtslint/ts3.5/Set.ts index 0821aa28b..b0a1ca574 100644 --- a/dtslint/ts3.5/Set.ts +++ b/dtslint/ts3.5/Set.ts @@ -1,5 +1,7 @@ import * as _ from '../../src/Set' import * as N from '../../src/number' +import { pipe } from '../../src/function' +import * as E from '../../src/Either' declare const me: Set @@ -37,3 +39,61 @@ _.intersection(N.Eq)(me) // $ExpectType (me: Set) => Set _.difference(N.Eq)(me, me) // $ExpectType Set _.difference(N.Eq)(me) // $ExpectType (me: Set) => Set + +// ------------------------------------------------------------------------------------- +// Predicate-based APIs +// ------------------------------------------------------------------------------------- + +declare const prns: Set +declare const prsns: Set +declare const isString: (u: unknown) => u is string +declare const isNumber: (sn: string | number) => sn is number +declare const predicate: (sn: string | number) => boolean + +// +// filter +// + +// $ExpectType Set +pipe(prsns, _.filter(isString)) +// $ExpectType Set +pipe(prns, _.filter(predicate)) +// $ExpectType Set +pipe( + prns, + _.filter( + ( + x // $ExpectType number + ) => true + ) +) + +// +// partition +// + +// $ExpectType Separated, Set> +pipe(prsns, _.partition(isString)) +// $ExpectType Separated, Set> +pipe(prns, _.partition(predicate)) +// $ExpectType Separated, Set> +pipe(prsns, _.partition(isNumber)) +// $ExpectType Separated, Set> +pipe( + prns, + _.partition( + ( + x // $ExpectType number + ) => true + ) +) + +// +// isEmpty +// + +// $ExpectType Either, Set> +pipe( + me, + E.fromPredicate(_.isEmpty, (as) => as) +) diff --git a/dtslint/ts3.5/TaskEither.ts b/dtslint/ts3.5/TaskEither.ts index b42992376..132d00946 100644 --- a/dtslint/ts3.5/TaskEither.ts +++ b/dtslint/ts3.5/TaskEither.ts @@ -1,6 +1,7 @@ import * as _ from '../../src/TaskEither' import * as T from '../../src/Task' import * as E from '../../src/Either' +import * as TO from '../../src/TaskOption' import * as IOE from '../../src/IOEither' import { pipe } from '../../src/function' @@ -14,6 +15,56 @@ pipe( _.getOrElseW(() => T.of(null)) ) +// +// orElse +// + +// $ExpectType TaskEither +pipe( + _.left('a'), + _.orElse((a) => _.left(a.length)) +) + +// +// orElseW +// + +// $ExpectType TaskEither +pipe( + _.left('a'), + _.orElseW((a) => _.right(a.length)) +) + +// +// orElseFirst +// + +// $ExpectType TaskEither +pipe( + _.left('a'), + _.orElseFirst((a) => _.right(a.length)) +) + +// +// orElseFirstW +// + +// $ExpectType TaskEither +pipe( + _.left('a'), + _.orElseFirstW((a) => _.left(a.length)) +) + +// +// orLeft +// + +// $ExpectType TaskEither +pipe( + _.left('a'), + _.orLeft((a) => T.of(a.length)) +) + // // chainW // @@ -44,6 +95,16 @@ pipe( _.chainIOEitherKW(() => IOE.right(1)) ) +// +// fromTaskOption +// + +// $ExpectType TaskEither +pipe( + TO.some(1), + _.fromTaskOption(() => 'a') +) + // // taskify // diff --git a/dtslint/ts3.5/TaskOption.ts b/dtslint/ts3.5/TaskOption.ts new file mode 100644 index 000000000..97c1b689b --- /dev/null +++ b/dtslint/ts3.5/TaskOption.ts @@ -0,0 +1,83 @@ +import * as _ from '../../src/TaskOption' +import * as TE from '../../src/TaskEither' +import { pipe } from '../../src/function' + +declare const tesn: TE.TaskEither + +// +// fromTaskEither +// + +pipe(tesn, _.fromTaskEither) // $ExpectType TaskOption + +// ------------------------------------------------------------------------------------- +// Predicate-based APIs +// ------------------------------------------------------------------------------------- + +declare const n: number +declare const sn: string | number +declare const on: _.TaskOption +declare const osn: _.TaskOption +declare const isString: (u: unknown) => u is string +declare const isNumber: (sn: string | number) => sn is number +declare const predicate: (sn: string | number) => boolean + +// +// filter +// + +// $ExpectType TaskOption +pipe(osn, _.filter(isString)) +// $ExpectType TaskOption +pipe(on, _.filter(predicate)) +// $ExpectType TaskOption +pipe( + on, + _.filter( + ( + x // $ExpectType number + ) => true + ) +) + +// +// partition +// + +// $ExpectType Separated, TaskOption> +pipe(osn, _.partition(isString)) +// $ExpectType Separated, TaskOption> +pipe(on, _.partition(predicate)) +// $ExpectType Separated, TaskOption> +pipe(osn, _.partition(isNumber)) +// $ExpectType Separated, TaskOption> +pipe( + on, + _.partition( + ( + x // $ExpectType number + ) => true + ) +) + +// +// fromPredicate +// + +// $ExpectType TaskOption +pipe(sn, _.fromPredicate(isString)) +// $ExpectType TaskOption +pipe(n, _.fromPredicate(predicate)) +// $ExpectType TaskOption +pipe( + n, + _.fromPredicate( + ( + n // $ExpectType number + ) => true + ) +) + +// +// filterOrElse +// diff --git a/package-lock.json b/package-lock.json index d245bf8cd..dd6274cb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "fp-ts", - "version": "2.10.0-rc.6", + "version": "2.11.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1072,27 +1072,6 @@ "@sinonjs/commons": "^1.7.0" } }, - "@textlint/ast-node-types": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-4.2.1.tgz", - "integrity": "sha512-Pqg1LTJpF929Ovi/lCaPqlyz8yDwBFbQulC0jyQcbRAoTxYS4AZMc48Ug2yk0so5hISQXKrlAxyVBmBVl9EKGA==", - "dev": true - }, - "@textlint/markdown-to-ast": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/@textlint/markdown-to-ast/-/markdown-to-ast-6.0.9.tgz", - "integrity": "sha512-hfAWBvTeUGh5t5kTn2U3uP3qOSM1BSrxzl1jF3nn0ywfZXpRBZr5yRjXnl4DzIYawCtZOshmRi/tI3/x4TE1jQ==", - "dev": true, - "requires": { - "@textlint/ast-node-types": "^4.0.3", - "debug": "^2.1.3", - "remark-frontmatter": "^1.2.0", - "remark-parse": "^5.0.0", - "structured-source": "^3.0.2", - "traverse": "^0.6.6", - "unified": "^6.1.6" - } - }, "@ts-morph/common": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.7.5.tgz", @@ -1309,15 +1288,6 @@ "uri-js": "^4.2.2" } }, - "anchor-markdown-header": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/anchor-markdown-header/-/anchor-markdown-header-0.5.7.tgz", - "integrity": "sha1-BFBj125qH5zTJ6V6ASaqD97Dcac=", - "dev": true, - "requires": { - "emoji-regex": "~6.1.0" - } - }, "ansi-escapes": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", @@ -1652,12 +1622,6 @@ "babel-preset-current-node-syntax": "^0.1.3" } }, - "bail": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.3.tgz", - "integrity": "sha512-1X8CnjFVQ+a+KW36uBNMTU5s8+v5FzeqrP7hTG5aTb4aPreSbZJlhwPon9VKMuEVgV++JM+SQrALY3kr7eswdg==", - "dev": true - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -1750,12 +1714,6 @@ "platform": "^1.3.3" } }, - "boundary": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/boundary/-/boundary-1.0.1.tgz", - "integrity": "sha1-TWfcJgLAzBbdm85+v4fpSCkPWBI=", - "dev": true - }, "brace-expansion": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", @@ -1897,24 +1855,6 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, - "character-entities": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.2.tgz", - "integrity": "sha512-sMoHX6/nBiy3KKfC78dnEalnpn0Az0oSNvqUWYTtYrhRI5iUIYsROU48G+E+kMFQzqXaJ8kHJZ85n7y6/PHgwQ==", - "dev": true - }, - "character-entities-legacy": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.2.tgz", - "integrity": "sha512-9NB2VbXtXYWdXzqrvAHykE/f0QJxzaKIpZ5QzNZrrgQ7Iyxr2vnfS8fCBNVW9nUEZE0lo57nxKRqnzY/dKrwlA==", - "dev": true - }, - "character-reference-invalid": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.2.tgz", - "integrity": "sha512-7I/xceXfKyUJmSAn/jw8ve/9DyOP7XxufNYLI9Px7CmsKgEUaZLUTax6nZxGQtaoiZCjpu6cHPj20xC/vqRReQ==", - "dev": true - }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -1996,12 +1936,6 @@ "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==", "dev": true }, - "collapse-white-space": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.4.tgz", - "integrity": "sha512-YfQ1tAUZm561vpYD+5eyWN8+UsceQbSrqqlc/6zDY2gtAE+uZLSdkkovhnGpmCThsvKBFakq4EdY/FF93E8XIw==", - "dev": true - }, "collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", @@ -2389,28 +2323,6 @@ } } }, - "doctoc": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/doctoc/-/doctoc-1.4.0.tgz", - "integrity": "sha512-8IAq3KdMkxhXCUF+xdZxdJxwuz8N2j25sMgqiu4U4JWluN9tRKMlAalxGASszQjlZaBprdD2YfXpL3VPWUD4eg==", - "dev": true, - "requires": { - "@textlint/markdown-to-ast": "~6.0.9", - "anchor-markdown-header": "^0.5.5", - "htmlparser2": "~3.9.2", - "minimist": "~1.2.0", - "underscore": "~1.8.3", - "update-section": "^0.3.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -2420,22 +2332,6 @@ "esutils": "^2.0.2" } }, - "dom-serializer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", - "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", - "dev": true, - "requires": { - "domelementtype": "^1.3.0", - "entities": "^1.1.1" - } - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, "domexception": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", @@ -2453,25 +2349,6 @@ } } }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, "dtslint": { "version": "github:gcanti/dtslint#824af7cf7780df9840b87d126835a40da740c064", "from": "github:gcanti/dtslint", @@ -2481,7 +2358,7 @@ "parsimmon": "^1.12.0", "strip-json-comments": "^2.0.1", "tslint": "^5.12.0", - "typescript": "^4.3.0-dev.20210310" + "typescript": "^4.3.0-dev.20210429" }, "dependencies": { "ansi-styles": { @@ -2556,9 +2433,9 @@ } }, "typescript": { - "version": "4.3.0-dev.20210310", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.0-dev.20210310.tgz", - "integrity": "sha512-k/FbuOXh6ASEGg8R468bfD6JJH9wX3woe+NtxcRHk8tXfH4lsU7RR4LZgEKa9ctfq5Df2Kvj2WyyTcHV2XYPsQ==", + "version": "4.3.0-dev.20210429", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.0-dev.20210429.tgz", + "integrity": "sha512-rBkCCg6odkGs1Xc2pKHhjwCCYm2wrx6LvqgbWAquRg7yRVFz6lNtRLfqc+q0Oc5N9BjnlcyWTAi+mqOZzIZUDA==", "dev": true } } @@ -2579,12 +2456,6 @@ "integrity": "sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==", "dev": true }, - "emoji-regex": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.3.tgz", - "integrity": "sha1-7HmjlpsC0uzytyJUJ5v5m8eoOTI=", - "dev": true - }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -2594,12 +2465,6 @@ "once": "^1.4.0" } }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2929,15 +2794,6 @@ "reusify": "^1.0.4" } }, - "fault": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.2.tgz", - "integrity": "sha512-o2eo/X2syzzERAtN5LcGbiVQ0WwZSlN3qLtadwAz3X8Bu+XWD16dja/KMsjZLiQr+BLGPDnHGkc4yUJf1Xpkpw==", - "dev": true, - "requires": { - "format": "^0.2.2" - } - }, "fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -2993,12 +2849,6 @@ "mime-types": "^2.1.12" } }, - "format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=", - "dev": true - }, "fp-ts": { "version": "2.9.5", "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.9.5.tgz", @@ -3281,20 +3131,6 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "htmlparser2": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", - "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", - "dev": true, - "requires": { - "domelementtype": "^1.3.0", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^2.0.2" - } - }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -3384,22 +3220,6 @@ "kind-of": "^3.0.2" } }, - "is-alphabetical": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.2.tgz", - "integrity": "sha512-V0xN4BYezDHcBSKb1QHUFMlR4as/XEuCZBzMJUU4n7+Cbt33SmUnSol+pnXFvLxSHNq2CemUXNdaXV6Flg7+xg==", - "dev": true - }, - "is-alphanumerical": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.2.tgz", - "integrity": "sha512-pyfU/0kHdISIgslFfZN9nfY1Gk3MquQgUm1mJTjdkEPpkAKNWuBTSqFwewOpR7N351VkErCiyV71zX7mlQQqsg==", - "dev": true, - "requires": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - } - }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -3430,12 +3250,6 @@ "kind-of": "^3.0.2" } }, - "is-decimal": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.2.tgz", - "integrity": "sha512-TRzl7mOCchnhchN+f3ICUCzYvL9ul7R+TYOsZ8xia++knyZAJfv/uA1FvQXsAnYIl1T3B2X5E/J7Wb1QXiIBXg==", - "dev": true - }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", @@ -3495,12 +3309,6 @@ "is-extglob": "^2.1.1" } }, - "is-hexadecimal": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.2.tgz", - "integrity": "sha512-but/G3sapV3MNyqiDBLrOi4x8uCIw0RY3o/Vb5GT0sMFHrVV7731wFSVy41T5FO1og7G0gXLJh0MkgPRouko/A==", - "dev": true - }, "is-negated-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", @@ -3516,12 +3324,6 @@ "kind-of": "^3.0.2" } }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -3575,24 +3377,12 @@ "unc-path-regex": "^0.1.2" } }, - "is-whitespace-character": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.2.tgz", - "integrity": "sha512-SzM+T5GKUCtLhlHFKt2SDAX2RFzfS6joT91F2/WSi9LxgFdsnhfPK/UIA+JhRR2xuyLdrCys2PiFDrtn1fU5hQ==", - "dev": true - }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0=", "dev": true }, - "is-word-character": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.2.tgz", - "integrity": "sha512-T3FlsX8rCHAH8e7RE7PfOPZVFQlcV3XRF9eOOBQ1uf70OxO7CjjSOjeImMPCADBdYWcStAbVbYvJ1m2D3tb+EA==", - "dev": true - }, "is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -5368,12 +5158,6 @@ "object-visit": "^1.0.0" } }, - "markdown-escapes": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.2.tgz", - "integrity": "sha512-lbRZ2mE3Q9RtLjxZBZ9+IMl68DKIXaVAhwvwn9pmjnPLS0h/6kyBMgNhqi1xFJ/2yv6cSyv0jbiZavZv93JkkA==", - "dev": true - }, "markdown-link": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/markdown-link/-/markdown-link-0.1.1.tgz", @@ -5868,20 +5652,6 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "parse-entities": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.1.tgz", - "integrity": "sha512-NBWYLQm1KSoDKk7GAHyioLTvCZ5QjdH/ASBBQTD3iLiAWJXS5bg1jEWI8nIJ+vgVvsceBVBcDGRWSo0KVQBvvg==", - "dev": true, - "requires": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, "parse-json": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", @@ -5901,9 +5671,9 @@ "dev": true }, "parsimmon": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/parsimmon/-/parsimmon-1.16.0.tgz", - "integrity": "sha512-tekGDz2Lny27SQ/5DzJdIK0lqsWwZ667SCLFIDCxaZM7VNgQjyKLbaL7FYPKpbjdxNAXFV/mSxkq5D2fnkW4pA==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/parsimmon/-/parsimmon-1.17.0.tgz", + "integrity": "sha512-gp5yNYs0Lyv5Mp6hj+JMzsHaM4Mel0WuK2iHYKX32ActYAQdsSq+t4nVsqlOpUCiMYdTX1wFISLvugrAl9harg==", "dev": true }, "pascalcase": { @@ -6178,39 +5948,6 @@ "safe-regex": "^1.1.0" } }, - "remark-frontmatter": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-1.3.1.tgz", - "integrity": "sha512-Zj/fDMYnSVgMCeKp8fXIhtMoZq4G6E1dnwfMoO8fVXrm/+oVSiN8YMREtwN2cctgK9EsnYSeS1ExX2hcX/fE1A==", - "dev": true, - "requires": { - "fault": "^1.0.1", - "xtend": "^4.0.1" - } - }, - "remark-parse": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz", - "integrity": "sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==", - "dev": true, - "requires": { - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^1.1.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^1.0.0", - "vfile-location": "^2.0.0", - "xtend": "^4.0.1" - } - }, "remarkable": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-1.7.4.tgz", @@ -6239,12 +5976,6 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true - }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -6904,12 +6635,6 @@ } } }, - "state-toggle": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.1.tgz", - "integrity": "sha512-Qe8QntFrrpWTnHwvwj2FZTgv+PKIsp0B9VxLzLLbSpPXWOgRgc5LVj/aTiSfK1RqIeF9jeC1UeOH8Q8y60A7og==", - "dev": true - }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -7046,15 +6771,6 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, - "structured-source": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/structured-source/-/structured-source-3.0.2.tgz", - "integrity": "sha1-3YAkJeD1PcSm56yjdSkBoczaevU=", - "dev": true, - "requires": { - "boundary": "^1.0.1" - } - }, "supports-color": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", @@ -7210,30 +6926,6 @@ "punycode": "^2.1.1" } }, - "traverse": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", - "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", - "dev": true - }, - "trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", - "dev": true - }, - "trim-trailing-lines": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.1.tgz", - "integrity": "sha512-bWLv9BbWbbd7mlqqs2oQYnLD/U/ZqeJeJwbO0FG2zA1aTq+HTvxfHNKFa/HGCVyJpDiioUYaBhfiT6rgk+l4mg==", - "dev": true - }, - "trough": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.3.tgz", - "integrity": "sha512-fwkLWH+DimvA4YCy+/nvJd61nWQQ2liO/nF/RjkTpiOGi+zxZzVkhb1mvbHIIW4b/8nDsYI8uTmAlc0nNkRMOw==", - "dev": true - }, "ts-jest": { "version": "26.3.0", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.3.0.tgz", @@ -7750,36 +7442,6 @@ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", "dev": true }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", - "dev": true - }, - "unherit": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.1.tgz", - "integrity": "sha512-+XZuV691Cn4zHsK0vkKYwBEwB74T3IZIcxrgn2E4rKwTfFyI1zCh7X7grwh9Re08fdPlarIdyWgI8aVB3F5A5g==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "xtend": "^4.0.1" - } - }, - "unified": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz", - "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==", - "dev": true, - "requires": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^1.1.0", - "trough": "^1.0.0", - "vfile": "^2.0.0", - "x-is-string": "^0.1.0" - } - }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -7792,45 +7454,6 @@ "set-value": "^2.0.1" } }, - "unist-util-is": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.2.tgz", - "integrity": "sha512-YkXBK/H9raAmG7KXck+UUpnKiNmUdB+aBGrknfQ4EreE1banuzrKABx3jP6Z5Z3fMSPMQQmeXBlKpCbMwBkxVw==", - "dev": true - }, - "unist-util-remove-position": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.2.tgz", - "integrity": "sha512-XxoNOBvq1WXRKXxgnSYbtCF76TJrRoe5++pD4cCBsssSiWSnPEktyFrFLE8LTk3JW5mt9hB0Sk5zn4x/JeWY7Q==", - "dev": true, - "requires": { - "unist-util-visit": "^1.1.0" - } - }, - "unist-util-stringify-position": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", - "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", - "dev": true - }, - "unist-util-visit": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.0.tgz", - "integrity": "sha512-FiGu34ziNsZA3ZUteZxSFaczIjGmksfSgdKqBfOejrrfzyUy5b7YrlzT1Bcvi+djkYDituJDy2XB7tGTeBieKw==", - "dev": true, - "requires": { - "unist-util-visit-parents": "^2.0.0" - } - }, - "unist-util-visit-parents": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.0.1.tgz", - "integrity": "sha512-6B0UTiMfdWql4cQ03gDTCSns+64Zkfo2OCbK31Ov0uMizEz+CJeAp0cgZVb5Fhmcd7Bct2iRNywejT0orpbqUA==", - "dev": true, - "requires": { - "unist-util-is": "^2.1.2" - } - }, "universalify": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", @@ -7883,12 +7506,6 @@ } } }, - "update-section": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/update-section/-/update-section-0.3.3.tgz", - "integrity": "sha1-RY8Xgg03gg3GDiC4bZQ5GwASMVg=", - "dev": true - }, "uri-js": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", @@ -7963,33 +7580,6 @@ "extsprintf": "^1.2.0" } }, - "vfile": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", - "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", - "dev": true, - "requires": { - "is-buffer": "^1.1.4", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-message": "^1.0.0" - } - }, - "vfile-location": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.4.tgz", - "integrity": "sha512-KRL5uXQPoUKu+NGvQVL4XLORw45W62v4U4gxJ3vRlDfI9QsT4ZN1PNXn/zQpKUulqGDpYuT0XDfp5q9O87/y/w==", - "dev": true - }, - "vfile-message": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", - "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", - "dev": true, - "requires": { - "unist-util-stringify-position": "^1.1.1" - } - }, "w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", @@ -8147,12 +7737,6 @@ "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", "dev": true }, - "x-is-string": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", - "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", - "dev": true - }, "xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", diff --git a/package.json b/package.json index ef21b9196..9ed77aa2e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fp-ts", - "version": "2.10.5", + "version": "2.11.0", "description": "Functional programming in TypeScript", "main": "lib/index.js", "module": "es6/index.js", @@ -22,7 +22,8 @@ "dtslint": "dtslint dtslint", "docs": "docs-ts", "prerelease": "npm run build", - "release": "ts-node scripts/release" + "release": "ts-node scripts/release", + "dpdm": "dpdm --warning=false --tree=false --exit-code circular:1 -T src/index.ts" }, "repository": { "type": "git", diff --git a/perf/Either/sequenceArray.ts b/perf/Either/sequenceArray.ts index be97170a3..7c071ce43 100644 --- a/perf/Either/sequenceArray.ts +++ b/perf/Either/sequenceArray.ts @@ -1,5 +1,5 @@ import * as Benchmark from 'benchmark' -import * as A from '../../src/Array' +import * as RNEA from '../../src/ReadonlyNonEmptyArray' import * as _ from '../../src/Either' import { pipe } from '../../src/function' @@ -11,13 +11,14 @@ Fastest is _.sequenceArray const suite = new Benchmark.Suite() -const as = pipe(A.range(0, 1000), A.map(_.of)) +const as = pipe(RNEA.range(0, 1000), RNEA.map(_.of)) suite .add('A.sequence(_.Applicative)', function () { - pipe(as, A.sequence(_.Applicative)) + pipe(as, RNEA.sequence(_.Applicative)) }) .add('_.sequenceArray', function () { + // tslint:disable-next-line: deprecation pipe(as, _.sequenceArray) }) .on('cycle', function (event: any) { diff --git a/perf/IO/sequenceArray.ts b/perf/IO/sequenceArray.ts index d1d50f710..44c88e5cd 100644 --- a/perf/IO/sequenceArray.ts +++ b/perf/IO/sequenceArray.ts @@ -1,5 +1,5 @@ import * as Benchmark from 'benchmark' -import * as A from '../../src/Array' +import * as RNEA from '../../src/ReadonlyNonEmptyArray' import * as _ from '../../src/IO' import { pipe } from '../../src/function' @@ -11,13 +11,14 @@ Fastest is _.sequenceArray const suite = new Benchmark.Suite() -const as = pipe(A.range(0, 1000), A.map(_.of)) +const as = pipe(RNEA.range(0, 1000), RNEA.map(_.of)) suite .add('A.sequence(_.Applicative)', function () { - pipe(as, A.sequence(_.Applicative)) + pipe(as, RNEA.sequence(_.Applicative)) }) .add('_.sequenceArray', function () { + // tslint:disable-next-line: deprecation pipe(as, _.sequenceArray) }) .on('cycle', function (event: any) { diff --git a/perf/Option/sequenceArray.ts b/perf/Option/sequenceArray.ts index 74b24d635..bb3b2a672 100644 --- a/perf/Option/sequenceArray.ts +++ b/perf/Option/sequenceArray.ts @@ -1,5 +1,5 @@ import * as Benchmark from 'benchmark' -import * as A from '../../src/Array' +import * as RNEA from '../../src/ReadonlyNonEmptyArray' import * as _ from '../../src/Option' import { pipe } from '../../src/function' @@ -11,13 +11,14 @@ Fastest is _.sequenceArray const suite = new Benchmark.Suite() -const as = pipe(A.range(0, 1000), A.map(_.of)) +const as = pipe(RNEA.range(0, 1000), RNEA.map(_.of)) suite .add('A.sequence(_.Applicative)', function () { - return pipe(as, A.sequence(_.Applicative)) + return pipe(as, RNEA.sequence(_.Applicative)) }) .add('_.sequenceArray', function () { + // tslint:disable-next-line: deprecation return pipe(as, _.sequenceArray) }) .on('cycle', function (event: any) { diff --git a/perf/ReaderTask/traverseSeqArrayWithIndex.ts b/perf/ReaderTask/traverseReadonlyArrayWithIndexSeq.ts similarity index 74% rename from perf/ReaderTask/traverseSeqArrayWithIndex.ts rename to perf/ReaderTask/traverseReadonlyArrayWithIndexSeq.ts index bbbc6816e..73a9b37cb 100644 --- a/perf/ReaderTask/traverseSeqArrayWithIndex.ts +++ b/perf/ReaderTask/traverseReadonlyArrayWithIndexSeq.ts @@ -1,5 +1,5 @@ import * as Benchmark from 'benchmark' -import * as A from '../../src/Array' +import * as RNEA from '../../src/ReadonlyNonEmptyArray' import * as _ from '../../src/ReaderTask' import { pipe } from '../../src/function' @@ -11,19 +11,19 @@ Fastest is _.traverseSeqArrayWithIndex const suite = new Benchmark.Suite() -const as = A.range(0, 1000) +const as = pipe(RNEA.range(0, 1000)) suite .add('A.traverseWithIndex(_.ApplicativeSeq)', function () { return pipe( as, - A.traverseWithIndex(_.ApplicativeSeq)((_i, a) => _.of(a)) + RNEA.traverseWithIndex(_.ApplicativeSeq)((_i, a) => _.of(a)) )(undefined)() }) - .add('_.traverseSeqArrayWithIndex', function () { + .add('_.traverseReadonlyArrayWithIndexSeq', function () { return pipe( as, - _.traverseSeqArrayWithIndex((_i, a) => _.of(a)) + _.traverseReadonlyArrayWithIndexSeq((_i, a) => _.of(a)) )(undefined)() }) .on('cycle', function (event: any) { diff --git a/perf/ReaderTaskEither/traverseSeqArrayWithIndex.ts b/perf/ReaderTaskEither/traverseReadonlyArrayWithIndexSeq.ts similarity index 74% rename from perf/ReaderTaskEither/traverseSeqArrayWithIndex.ts rename to perf/ReaderTaskEither/traverseReadonlyArrayWithIndexSeq.ts index 78237b8cd..f348fc6f1 100644 --- a/perf/ReaderTaskEither/traverseSeqArrayWithIndex.ts +++ b/perf/ReaderTaskEither/traverseReadonlyArrayWithIndexSeq.ts @@ -1,5 +1,5 @@ import * as Benchmark from 'benchmark' -import * as A from '../../src/Array' +import * as RNEA from '../../src/ReadonlyNonEmptyArray' import * as _ from '../../src/ReaderTaskEither' import { pipe } from '../../src/function' @@ -11,19 +11,19 @@ Fastest is _.traverseSeqArrayWithIndex const suite = new Benchmark.Suite() -const as = A.range(0, 1000) +const as = pipe(RNEA.range(0, 1000)) suite .add('A.traverseWithIndex(_.ApplicativeSeq)', function () { return pipe( as, - A.traverseWithIndex(_.ApplicativeSeq)((_i, a) => _.of(a)) + RNEA.traverseWithIndex(_.ApplicativeSeq)((_i, a) => _.of(a)) )(undefined)() }) - .add('_.traverseSeqArrayWithIndex', function () { + .add('_.traverseReadonlyArrayWithIndexSeq', function () { return pipe( as, - _.traverseSeqArrayWithIndex((_i, a) => _.of(a)) + _.traverseReadonlyArrayWithIndexSeq((_i, a) => _.of(a)) )(undefined)() }) .on('cycle', function (event: any) { diff --git a/perf/StateReaderTaskEither/sequenceArray.ts b/perf/StateReaderTaskEither/sequenceArray.ts index a9e7eaa81..7a45b8736 100644 --- a/perf/StateReaderTaskEither/sequenceArray.ts +++ b/perf/StateReaderTaskEither/sequenceArray.ts @@ -1,5 +1,5 @@ import * as Benchmark from 'benchmark' -import * as A from '../../src/Array' +import * as RNEA from '../../src/ReadonlyNonEmptyArray' import * as _ from '../../src/StateReaderTaskEither' import { pipe } from '../../src/function' @@ -11,13 +11,14 @@ Fastest is _.sequenceArray const suite = new Benchmark.Suite() -const as = pipe(A.range(0, 1000), A.map(_.of)) +const as = pipe(RNEA.range(0, 1000), RNEA.map(_.of)) suite .add('A.sequence(_.Applicative)', function () { - pipe(as, A.sequence(_.Applicative)) + pipe(as, RNEA.sequence(_.Applicative)) }) .add('_.sequenceArray', function () { + // tslint:disable-next-line: deprecation pipe(as, _.sequenceArray) }) .on('cycle', function (event: any) { diff --git a/perf/Task/sequenceArray.ts b/perf/Task/sequenceArray.ts index 69d40c6f5..34a8f528f 100644 --- a/perf/Task/sequenceArray.ts +++ b/perf/Task/sequenceArray.ts @@ -1,5 +1,5 @@ import * as Benchmark from 'benchmark' -import * as A from '../../src/Array' +import * as RNEA from '../../src/ReadonlyNonEmptyArray' import * as _ from '../../src/Task' import { pipe } from '../../src/function' @@ -11,13 +11,14 @@ Fastest is _.sequenceArray const suite = new Benchmark.Suite() -const as = pipe(A.range(0, 1000), A.map(_.of)) +const as = pipe(RNEA.range(0, 1000), RNEA.map(_.of)) suite .add('A.sequence(_.ApplicativePar)', function () { - return pipe(as, A.sequence(_.ApplicativePar))() + return pipe(as, RNEA.sequence(_.ApplicativePar))() }) .add('_.sequenceArray', function () { + // tslint:disable-next-line: deprecation return pipe(as, _.sequenceArray)() }) .on('cycle', function (event: any) { diff --git a/perf/Task/stack.ts b/perf/Task/stack.ts index e6f2ce100..f9e11010b 100644 --- a/perf/Task/stack.ts +++ b/perf/Task/stack.ts @@ -1,12 +1,13 @@ -import * as A from '../../src/Array' +import * as RNEA from '../../src/ReadonlyNonEmptyArray' import * as _ from '../../src/Task' import { pipe } from '../../src/function' -const as = A.range(0, 100000) +const as = RNEA.range(0, 100000) // tslint:disable-next-line: no-floating-promises pipe( as, + // tslint:disable-next-line: deprecation _.traverseSeqArrayWithIndex((_i, a) => _.of(a)) // tslint:disable-next-line: no-console )().then((as) => console.log(as.length)) diff --git a/perf/Task/traverseSeqArrayWithIndex.ts b/perf/Task/traverseReadonlyArrayWithIndexSeq.ts similarity index 74% rename from perf/Task/traverseSeqArrayWithIndex.ts rename to perf/Task/traverseReadonlyArrayWithIndexSeq.ts index 54df0d198..976e117d1 100644 --- a/perf/Task/traverseSeqArrayWithIndex.ts +++ b/perf/Task/traverseReadonlyArrayWithIndexSeq.ts @@ -1,5 +1,5 @@ import * as Benchmark from 'benchmark' -import * as A from '../../src/Array' +import * as RNEA from '../../src/ReadonlyNonEmptyArray' import * as _ from '../../src/Task' import { pipe } from '../../src/function' @@ -11,19 +11,19 @@ Fastest is _.traverseSeqArrayWithIndex const suite = new Benchmark.Suite() -const as = A.range(0, 1000) +const as = pipe(RNEA.range(0, 1000)) suite .add('A.traverseWithIndex(_.ApplicativeSeq)', function () { return pipe( as, - A.traverseWithIndex(_.ApplicativeSeq)((_i, a) => _.of(a)) + RNEA.traverseWithIndex(_.ApplicativeSeq)((_i, a) => _.of(a)) )() }) - .add('_.traverseSeqArrayWithIndex', function () { + .add('_.traverseReadonlyArrayWithIndexSeq', function () { return pipe( as, - _.traverseSeqArrayWithIndex((_i, a) => _.of(a)) + _.traverseReadonlyArrayWithIndexSeq((_i, a) => _.of(a)) )() }) .on('cycle', function (event: any) { diff --git a/perf/TaskEither/traverseSeqArrayWithIndex.ts b/perf/TaskEither/traverseReadonlyArrayWithIndexSeq.ts similarity index 74% rename from perf/TaskEither/traverseSeqArrayWithIndex.ts rename to perf/TaskEither/traverseReadonlyArrayWithIndexSeq.ts index b3fd4a21d..f380e4596 100644 --- a/perf/TaskEither/traverseSeqArrayWithIndex.ts +++ b/perf/TaskEither/traverseReadonlyArrayWithIndexSeq.ts @@ -1,5 +1,5 @@ import * as Benchmark from 'benchmark' -import * as A from '../../src/Array' +import * as RNEA from '../../src/ReadonlyNonEmptyArray' import * as _ from '../../src/TaskEither' import { pipe } from '../../src/function' @@ -11,19 +11,19 @@ Fastest is _.traverseSeqArrayWithIndex const suite = new Benchmark.Suite() -const as = A.range(0, 1000) +const as = pipe(RNEA.range(0, 1000)) suite .add('A.traverseWithIndex(_.ApplicativeSeq)', function () { return pipe( as, - A.traverseWithIndex(_.ApplicativeSeq)((_i, a) => _.of(a)) + RNEA.traverseWithIndex(_.ApplicativeSeq)((_i, a) => _.of(a)) )() }) - .add('_.traverseSeqArrayWithIndex', function () { + .add('_.traverseReadonlyArrayWithIndexSeq', function () { return pipe( as, - _.traverseSeqArrayWithIndex((_i, a) => _.of(a)) + _.traverseReadonlyArrayWithIndexSeq((_i, a) => _.of(a)) )() }) .on('cycle', function (event: any) { diff --git a/perf/TaskOption.ts/traverseSeqArrayWithIndex.ts b/perf/TaskOption.ts/traverseReadonlyArrayWithIndexSeq.ts similarity index 74% rename from perf/TaskOption.ts/traverseSeqArrayWithIndex.ts rename to perf/TaskOption.ts/traverseReadonlyArrayWithIndexSeq.ts index 0d4bcf2b2..0fd892612 100644 --- a/perf/TaskOption.ts/traverseSeqArrayWithIndex.ts +++ b/perf/TaskOption.ts/traverseReadonlyArrayWithIndexSeq.ts @@ -1,5 +1,5 @@ import * as Benchmark from 'benchmark' -import * as A from '../../src/Array' +import * as RNEA from '../../src/ReadonlyNonEmptyArray' import * as _ from '../../src/TaskOption' import { pipe } from '../../src/function' @@ -11,19 +11,19 @@ Fastest is _.traverseSeqArrayWithIndex const suite = new Benchmark.Suite() -const as = A.range(0, 1000) +const as = pipe(RNEA.range(0, 1000)) suite .add('A.traverseWithIndex(_.ApplicativeSeq)', function () { return pipe( as, - A.traverseWithIndex(_.ApplicativeSeq)((_i, a) => _.of(a)) + RNEA.traverseWithIndex(_.ApplicativeSeq)((_i, a) => _.of(a)) )() }) - .add('_.traverseSeqArrayWithIndex', function () { + .add('_.traverseReadonlyArrayWithIndexSeq', function () { return pipe( as, - _.traverseSeqArrayWithIndex((_i, a) => _.of(a)) + _.traverseReadonlyArrayWithIndexSeq((_i, a) => _.of(a)) )() }) .on('cycle', function (event: any) { diff --git a/perf/TaskOption/traverseSeqArrayWithIndex.ts b/perf/TaskOption/traverseReadonlyArrayWithIndexSeq.ts similarity index 74% rename from perf/TaskOption/traverseSeqArrayWithIndex.ts rename to perf/TaskOption/traverseReadonlyArrayWithIndexSeq.ts index 0d4bcf2b2..0fd892612 100644 --- a/perf/TaskOption/traverseSeqArrayWithIndex.ts +++ b/perf/TaskOption/traverseReadonlyArrayWithIndexSeq.ts @@ -1,5 +1,5 @@ import * as Benchmark from 'benchmark' -import * as A from '../../src/Array' +import * as RNEA from '../../src/ReadonlyNonEmptyArray' import * as _ from '../../src/TaskOption' import { pipe } from '../../src/function' @@ -11,19 +11,19 @@ Fastest is _.traverseSeqArrayWithIndex const suite = new Benchmark.Suite() -const as = A.range(0, 1000) +const as = pipe(RNEA.range(0, 1000)) suite .add('A.traverseWithIndex(_.ApplicativeSeq)', function () { return pipe( as, - A.traverseWithIndex(_.ApplicativeSeq)((_i, a) => _.of(a)) + RNEA.traverseWithIndex(_.ApplicativeSeq)((_i, a) => _.of(a)) )() }) - .add('_.traverseSeqArrayWithIndex', function () { + .add('_.traverseReadonlyArrayWithIndexSeq', function () { return pipe( as, - _.traverseSeqArrayWithIndex((_i, a) => _.of(a)) + _.traverseReadonlyArrayWithIndexSeq((_i, a) => _.of(a)) )() }) .on('cycle', function (event: any) { diff --git a/scripts/build.ts b/scripts/build.ts index 5e311cf25..67d1d2fe3 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -33,7 +33,7 @@ export const FILES: ReadonlyArray = ['CHANGELOG.md', 'LICENSE', 'README. export const copyFiles: Build> = (C) => pipe( FILES, - TE.traverseArrayWithIndex((_, from) => C.copyFile(from, path.resolve(OUTPUT_FOLDER, from))) + TE.traverseReadonlyArrayWithIndex((_, from) => C.copyFile(from, path.resolve(OUTPUT_FOLDER, from))) ) export const makeModules: Build = (C) => { @@ -41,7 +41,7 @@ export const makeModules: Build = (C) => { return pipe( C.glob(`${OUTPUT_FOLDER}/lib/*.js`), TE.map(getModules), - TE.chain(TE.traverseArrayWithIndex((_, a) => makeSingleModuleC(a))), + TE.chain(TE.traverseReadonlyArrayWithIndex((_, a) => makeSingleModuleC(a))), TE.map(() => undefined) ) } diff --git a/src/Alt.ts b/src/Alt.ts index 3d0bb5eaa..1f0a4ae1c 100644 --- a/src/Alt.ts +++ b/src/Alt.ts @@ -73,3 +73,33 @@ export interface Alt3C extends Functor3C { export interface Alt4 extends Functor4 { readonly alt: (fa: Kind4, that: Lazy>) => Kind4 } + +// ------------------------------------------------------------------------------------- +// utils +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export function altAll( + F: Alt4 +): (startWith: Kind4) => (as: ReadonlyArray>) => Kind4 +export function altAll( + F: Alt3 +): (startWith: Kind3) => (as: ReadonlyArray>) => Kind3 +export function altAll( + F: Alt3C +): (startWith: Kind3) => (as: ReadonlyArray>) => Kind3 +export function altAll( + F: Alt2 +): (startWith: Kind2) => (as: ReadonlyArray>) => Kind2 +export function altAll( + F: Alt2C +): (startWith: Kind2) => (as: ReadonlyArray>) => Kind2 +export function altAll( + F: Alt1 +): (startWith: Kind) => (as: ReadonlyArray>) => Kind +export function altAll(F: Alt): (startWith: HKT) => (as: ReadonlyArray>) => HKT +export function altAll(F: Alt): (startWith: HKT) => (as: ReadonlyArray>) => HKT { + return (startWith) => (as) => as.reduce((acc, a) => F.alt(acc, () => a), startWith) +} diff --git a/src/Alternative.ts b/src/Alternative.ts index 434302646..69d151870 100644 --- a/src/Alternative.ts +++ b/src/Alternative.ts @@ -14,7 +14,7 @@ * * @since 2.0.0 */ -import { Alt, Alt1, Alt2, Alt2C, Alt3, Alt3C, Alt4 } from './Alt' +import { Alt, Alt1, Alt2, Alt2C, Alt3, Alt3C, Alt4, altAll as altAll_ } from './Alt' import { Applicative, Applicative1, @@ -25,6 +25,7 @@ import { Applicative4 } from './Applicative' import { HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT' +import { Zero, Zero1, Zero2, Zero2C, Zero3, Zero3C, Zero4 } from './Zero' // ------------------------------------------------------------------------------------- // model @@ -34,54 +35,66 @@ import { HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT * @category type classes * @since 2.0.0 */ -export interface Alternative extends Applicative, Alt { - readonly zero: () => HKT -} +export interface Alternative extends Applicative, Alt, Zero {} /** * @category type classes * @since 2.0.0 */ -export interface Alternative1 extends Applicative1, Alt1 { - readonly zero: () => Kind -} +export interface Alternative1 extends Applicative1, Alt1, Zero1 {} /** * @category type classes * @since 2.0.0 */ -export interface Alternative2 extends Applicative2, Alt2 { - readonly zero: () => Kind2 -} +export interface Alternative2 extends Applicative2, Alt2, Zero2 {} /** * @category type classes * @since 2.0.0 */ -export interface Alternative2C extends Applicative2C, Alt2C { - readonly zero: () => Kind2 -} +export interface Alternative2C extends Applicative2C, Alt2C, Zero2C {} /** * @category type classes * @since 2.0.0 */ -export interface Alternative3 extends Applicative3, Alt3 { - readonly zero: () => Kind3 -} +export interface Alternative3 extends Applicative3, Alt3, Zero3 {} /** * @category type classes * @since 2.10.0 */ -export interface Alternative3C extends Applicative3C, Alt3C { - readonly zero: () => Kind3 -} +export interface Alternative3C extends Applicative3C, Alt3C, Zero3C {} /** * @category type classes * @since 2.10.0 */ -export interface Alternative4 extends Applicative4, Alt4 { - readonly zero: () => Kind4 +export interface Alternative4 extends Applicative4, Alt4, Zero4 {} + +// ------------------------------------------------------------------------------------- +// utils +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export function altAll( + F: Alternative4 +): (as: ReadonlyArray>) => Kind4 +export function altAll( + F: Alternative3 +): (as: ReadonlyArray>) => Kind3 +export function altAll( + F: Alternative3C +): (as: ReadonlyArray>) => Kind3 +export function altAll(F: Alternative2): (as: ReadonlyArray>) => Kind2 +export function altAll( + F: Alternative2C +): (as: ReadonlyArray>) => Kind2 +export function altAll(F: Alternative1): (as: ReadonlyArray>) => Kind +export function altAll(F: Alternative): (as: ReadonlyArray>) => HKT +export function altAll(F: Alternative): (as: ReadonlyArray>) => HKT { + return altAll_(F)(F.zero()) } diff --git a/src/Array.ts b/src/Array.ts index ee1b34d46..f1269639c 100644 --- a/src/Array.ts +++ b/src/Array.ts @@ -6,6 +6,7 @@ import { Alternative1 } from './Alternative' import { Applicative as ApplicativeHKT, Applicative1 } from './Applicative' import { apFirst as apFirst_, Apply1, apS as apS_, apSecond as apSecond_ } from './Apply' import { bind as bind_, Chain1, chainFirst as chainFirst_ } from './Chain' +import { ChainRec1 } from './ChainRec' import { Compactable1 } from './Compactable' import { Either } from './Either' import { Eq } from './Eq' @@ -14,27 +15,65 @@ import { Filterable1 } from './Filterable' import { FilterableWithIndex1, PredicateWithIndex, RefinementWithIndex } from './FilterableWithIndex' import { Foldable1 } from './Foldable' import { FoldableWithIndex1 } from './FoldableWithIndex' -import { identity, Lazy, pipe, Predicate, Refinement } from './function' +import { FromEither1, fromEitherK as fromEitherK_ } from './FromEither' +import { identity, Lazy, pipe } from './function' import { bindTo as bindTo_, flap as flap_, Functor1 } from './Functor' import { FunctorWithIndex1 } from './FunctorWithIndex' import { HKT } from './HKT' +import * as _ from './internal' +import { Magma } from './Magma' import { Monad1 } from './Monad' import { Monoid } from './Monoid' +import { NaturalTransformation11 } from './NaturalTransformation' import * as NEA from './NonEmptyArray' -import * as O from './Option' +import { Option, URI as OURI } from './Option' import { Ord } from './Ord' import { Pointed1 } from './Pointed' +import { Predicate } from './Predicate' import * as RA from './ReadonlyArray' +import { Refinement } from './Refinement' import { Semigroup } from './Semigroup' import { separated, Separated } from './Separated' import { Show } from './Show' import { PipeableTraverse1, Traversable1 } from './Traversable' import { PipeableTraverseWithIndex1, TraversableWithIndex1 } from './TraversableWithIndex' import { Unfoldable1 } from './Unfoldable' -import { PipeableWilt1, PipeableWither1, Witherable1 } from './Witherable' +import { + filterE as filterE_, + PipeableWilt1, + PipeableWither1, + wiltDefault, + Witherable1, + witherDefault +} from './Witherable' +import { Zero1, guard as guard_ } from './Zero' import NonEmptyArray = NEA.NonEmptyArray -import Option = O.Option + +// ------------------------------------------------------------------------------------- +// refinements +// ------------------------------------------------------------------------------------- + +/** + * Test whether an array is empty + * + * @example + * import { isEmpty } from 'fp-ts/Array' + * + * assert.strictEqual(isEmpty([]), true) + * + * @category refinements + * @since 2.0.0 + */ +export const isEmpty = (as: Array): as is [] => as.length === 0 + +/** + * Test whether an array is non empty narrowing down the type to `NonEmptyArray` + * + * @category refinements + * @since 2.0.0 + */ +export const isNonEmpty: (as: Array) => as is NonEmptyArray = NEA.isNonEmpty // ------------------------------------------------------------------------------------- // constructors @@ -54,6 +93,14 @@ import Option = O.Option */ export const prepend: (head: A) => (tail: Array) => NEA.NonEmptyArray = NEA.prepend +/** + * Less strict version of [`prepend`](#prepend). + * + * @category constructors + * @since 2.11.0 + */ +export const prependW: (head: B) => (tail: Array) => NEA.NonEmptyArray = NEA.prependW + /** * Append an element to the end of a `Array`, creating a new `NonEmptyArray`. * @@ -68,6 +115,14 @@ export const prepend: (head: A) => (tail: Array) => NEA.NonEmptyArray = */ export const append: (end: A) => (init: Array) => NEA.NonEmptyArray = NEA.append +/** + * Less strict version of [`append`](#append). + * + * @category constructors + * @since 2.11.0 + */ +export const appendW: (end: B) => (init: Array) => NEA.NonEmptyArray = NEA.appendW + /** * Return a `Array` of length `n` with element `i` initialized with `f(i)`. * @@ -82,21 +137,7 @@ export const append: (end: A) => (init: Array) => NEA.NonEmptyArray = N * @category constructors * @since 2.0.0 */ -export const makeBy = (n: number, f: (i: number) => A): Array => (n <= 0 ? [] : NEA.makeBy(n, f)) - -/** - * Create an `Array` containing a range of integers, including both endpoints. - * - * @example - * import { range } from 'fp-ts/Array' - * - * assert.deepStrictEqual(range(1, 5), [1, 2, 3, 4, 5]) - * - * @category constructors - * @since 2.0.0 - */ -export const range = (start: number, end: number): Array => - start <= end ? makeBy(end - start + 1, (i) => start + i) : [start] +export const makeBy = (n: number, f: (i: number) => A): Array => (n <= 0 ? [] : NEA.makeBy(f)(n)) /** * Create a `Array` containing a value repeated the specified number of times. @@ -113,12 +154,66 @@ export const range = (start: number, end: number): Array => */ export const replicate = (n: number, a: A): Array => makeBy(n, () => a) +/** + * @category constructors + * @since 2.11.0 + */ +export function fromPredicate(refinement: Refinement): (a: A) => Array +export function fromPredicate(predicate: Predicate): (b: B) => Array +export function fromPredicate(predicate: Predicate): (a: A) => Array +export function fromPredicate(predicate: Predicate): (a: A) => Array { + return (a) => (predicate(a) ? [a] : []) +} + +// ------------------------------------------------------------------------------------- +// natural transformations +// ------------------------------------------------------------------------------------- + +/** + * @category natural transformations + * @since 2.11.0 + */ +export const fromOption: NaturalTransformation11 = (ma) => (_.isNone(ma) ? [] : [ma.value]) + +/** + * @category natural transformations + * @since 2.11.0 + */ +export const fromEither: FromEither1['fromEither'] = (e) => (_.isLeft(e) ? [] : [e.right]) + // ------------------------------------------------------------------------------------- // destructors // ------------------------------------------------------------------------------------- /** - * Break an array into its first element and remaining elements + * Less strict version of [`match`](#match). + * + * @category destructors + * @since 2.11.0 + */ +export const matchW = (onEmpty: Lazy, onNonEmpty: (as: NonEmptyArray) => C) => (as: Array): B | C => + isNonEmpty(as) ? onNonEmpty(as) : onEmpty() + +/** + * Less strict version of [`match`](#match). + * + * @category destructors + * @since 2.11.0 + */ +export const match: (onEmpty: Lazy, onNonEmpty: (as: NonEmptyArray) => B) => (as: Array) => B = matchW + +/** + * Less strict version of [`matchLeft`](#matchleft). + * + * @category destructors + * @since 2.11.0 + */ +export const matchLeftW = (onEmpty: Lazy, onNonEmpty: (head: A, tail: Array) => C) => ( + as: Array +): B | C => (isNonEmpty(as) ? onNonEmpty(NEA.head(as), NEA.tail(as)) : onEmpty()) + +/** + * Break an `Array` into its first element and remaining elements. * * @example * import { matchLeft } from 'fp-ts/Array' @@ -129,8 +224,10 @@ export const replicate = (n: number, a: A): Array => makeBy(n, () => a) * @category destructors * @since 2.10.0 */ -export const matchLeft = (onEmpty: Lazy, onNonEmpty: (head: A, tail: Array) => B) => (as: Array): B => - isNonEmpty(as) ? onNonEmpty(NEA.head(as), NEA.tail(as)) : onEmpty() +export const matchLeft: ( + onEmpty: Lazy, + onNonEmpty: (head: A, tail: Array) => B +) => (as: Array) => B = matchLeftW /** * Alias of [`matchLeft`](#matchleft). @@ -144,13 +241,25 @@ export const foldLeft: ( ) => (as: Array) => B = matchLeft /** - * Break an array into its initial elements and the last element + * Less strict version of [`matchRight`](#matchright). + * + * @category destructors + * @since 2.11.0 + */ +export const matchRightW = (onEmpty: Lazy, onNonEmpty: (init: Array, last: A) => C) => ( + as: Array +): B | C => (isNonEmpty(as) ? onNonEmpty(NEA.init(as), NEA.last(as)) : onEmpty()) + +/** + * Break an `Array` into its initial elements and the last element. * * @category destructors * @since 2.10.0 */ -export const matchRight = (onEmpty: Lazy, onNonEmpty: (init: Array, last: A) => B) => (as: Array): B => - isNonEmpty(as) ? onNonEmpty(NEA.init(as), NEA.last(as)) : onEmpty() +export const matchRight: ( + onEmpty: Lazy, + onNonEmpty: (init: Array, last: A) => B +) => (as: Array) => B = matchRightW /** * Alias of [`matchRight`](#matchright). @@ -221,26 +330,6 @@ export const scanRight = (b: B, f: (a: A, b: B) => B) => (as: Array): N return out } -/** - * Test whether an array is empty - * - * @example - * import { isEmpty } from 'fp-ts/Array' - * - * assert.strictEqual(isEmpty([]), true) - * - * @since 2.0.0 - */ -export const isEmpty: (as: Array) => boolean = RA.isEmpty - -/** - * Test whether an array is non empty narrowing down the type to `NonEmptyArray` - * - * @category guards - * @since 2.0.0 - */ -export const isNonEmpty: (as: Array) => as is NonEmptyArray = NEA.isNonEmpty - /** * Calculate the number of elements in a `Array`. * @@ -317,7 +406,7 @@ export const last: (as: Array) => Option = RA.last * @category destructors * @since 2.0.0 */ -export const tail = (as: Array): Option> => (isNonEmpty(as) ? O.some(NEA.tail(as)) : O.none) +export const tail = (as: Array): Option> => (isNonEmpty(as) ? _.some(NEA.tail(as)) : _.none) /** * Get all but the last element of an array, creating a new array, or `None` if the array is empty @@ -332,7 +421,7 @@ export const tail = (as: Array): Option> => (isNonEmpty(as) ? O.s * @category destructors * @since 2.0.0 */ -export const init = (as: Array): Option> => (isNonEmpty(as) ? O.some(NEA.init(as)) : O.none) +export const init = (as: Array): Option> => (isNonEmpty(as) ? _.some(NEA.init(as)) : _.none) /** * Keep only a max number of elements from the start of an `Array`, creating a new `Array`. @@ -377,9 +466,10 @@ export const takeRight = (n: number) => (as: Array): Array => * @since 2.0.0 */ export function takeLeftWhile(refinement: Refinement): (as: Array) => Array +export function takeLeftWhile(predicate: Predicate): (bs: Array) => Array export function takeLeftWhile(predicate: Predicate): (as: Array) => Array export function takeLeftWhile(predicate: Predicate): (as: Array) => Array { - return (as) => { + return (as: Array) => { const out: Array = [] for (const a of as) { if (!predicate(a)) { @@ -426,6 +516,7 @@ export interface Spanned { * @since 2.0.0 */ export function spanLeft(refinement: Refinement): (as: Array) => Spanned +export function spanLeft(predicate: Predicate): (bs: Array) => Spanned export function spanLeft(predicate: Predicate): (as: Array) => Spanned export function spanLeft(predicate: Predicate): (as: Array) => Spanned { return (as) => { @@ -477,8 +568,12 @@ export const dropRight = (n: number) => (as: Array): Array => * @category combinators * @since 2.0.0 */ -export const dropLeftWhile = (predicate: Predicate) => (as: Array): Array => - as.slice(spanLeftIndex(as, predicate)) +export function dropLeftWhile(refinement: Refinement): (as: Array) => Array +export function dropLeftWhile(predicate: Predicate): (bs: Array) => Array +export function dropLeftWhile(predicate: Predicate): (as: Array) => Array +export function dropLeftWhile(predicate: Predicate): (as: Array) => Array { + return (as) => as.slice(spanLeftIndex(as, predicate)) +} /** * Find the first index for which a predicate holds @@ -512,6 +607,7 @@ export const findIndex: (predicate: Predicate) => (as: Array) => Option * @since 2.0.0 */ export function findFirst(refinement: Refinement): (as: Array) => Option +export function findFirst(predicate: Predicate): (bs: Array) => Option export function findFirst(predicate: Predicate): (as: Array) => Option export function findFirst(predicate: Predicate): (as: Array) => Option { return RA.findFirst(predicate) @@ -557,6 +653,7 @@ export const findFirstMap: (f: (a: A) => Option) => (as: Array) => O * @since 2.0.0 */ export function findLast(refinement: Refinement): (as: Array) => Option +export function findLast(predicate: Predicate): (bs: Array) => Option export function findLast(predicate: Predicate): (as: Array) => Option export function findLast(predicate: Predicate): (as: Array) => Option { return RA.findLast(predicate) @@ -622,7 +719,7 @@ export const copy = (as: Array): Array => as.slice() * @since 2.0.0 */ export const insertAt = (i: number, a: A) => (as: Array): Option> => - i < 0 || i > as.length ? O.none : O.some(unsafeInsertAt(i, a, as)) + i < 0 || i > as.length ? _.none : _.some(unsafeInsertAt(i, a, as)) /** * Change the element at the specified index, creating a new array, or returning `None` if the index is out of bounds @@ -651,7 +748,7 @@ export const updateAt = (i: number, a: A): ((as: Array) => Option * @since 2.0.0 */ export const deleteAt = (i: number) => (as: Array): Option> => - isOutOfBound(i, as) ? O.none : O.some(unsafeDeleteAt(i, as)) + isOutOfBound(i, as) ? _.none : _.some(unsafeDeleteAt(i, as)) /** * Apply a function to the element at the specified index, creating a new array, or returning `None` if the index is out @@ -668,7 +765,7 @@ export const deleteAt = (i: number) => (as: Array): Option> => * @since 2.0.0 */ export const modifyAt = (i: number, f: (a: A) => A) => (as: Array): Option> => - isOutOfBound(i, as) ? O.none : O.some(unsafeUpdateAt(i, f(as[i]), as)) + isOutOfBound(i, as) ? _.none : _.some(unsafeUpdateAt(i, f(as[i]), as)) /** * Reverse an array, creating a new array @@ -997,6 +1094,13 @@ export const chunksOf = (n: number): ((as: Array) => Array (isNonEmpty(as) ? f(as) : []) } +/** + * @category combinators + * @since 2.11.0 + */ +export const fromOptionK = , B>(f: (...a: A) => Option) => (...a: A): Array => + fromOption(f(...a)) + /** * `Array` comprehension. * @@ -1051,6 +1155,19 @@ export function comprehension( return go([], input) } +/** + * @category combinators + * @since 2.11.0 + */ +export const concatW = (second: Array) => (first: Array): Array => + isEmpty(first) ? copy(second) : isEmpty(second) ? copy(first) : (first as Array).concat(second) + +/** + * @category combinators + * @since 2.11.0 + */ +export const concat: (second: Array) => (first: Array) => Array = concatW + // TODO: remove non-curried overloading in v3 /** * Creates an array of unique values, in order, from all given arrays using a `Eq` for equality comparisons @@ -1076,10 +1193,10 @@ export function union(E: Eq): (xs: Array, ys?: Array) => Array | return (first, second?) => { if (second === undefined) { const unionE = union(E) - return (ys) => unionE(ys, first) + return (second) => unionE(second, first) } return isNonEmpty(first) && isNonEmpty(second) - ? unionE(first, second) + ? unionE(second)(first) : isNonEmpty(first) ? copy(first) : copy(second) @@ -1225,20 +1342,8 @@ const _traverseWithIndex: TraversableWithIndex1['traverseWithIndex' const traverseWithIndexF = traverseWithIndex(F) return (ta, f) => pipe(ta, traverseWithIndexF(f)) } -/* istanbul ignore next */ -const _wither: Witherable1['wither'] = ( - F: ApplicativeHKT -): ((ta: Array, f: (a: A) => HKT>) => HKT>) => { - const witherF = wither(F) - return (fa, f) => pipe(fa, witherF(f)) -} -/* istanbul ignore next */ -const _wilt: Witherable1['wilt'] = ( - F: ApplicativeHKT -): ((fa: Array, f: (a: A) => HKT>) => HKT, Array>>) => { - const wiltF = wilt(F) - return (fa, f) => pipe(fa, wiltF(f)) -} +const _chainRecDepthFirst: ChainRec1['chainRec'] = RA._chainRecDepthFirst as any +const _chainRecBreadthFirst: ChainRec1['chainRec'] = RA._chainRecBreadthFirst as any // ------------------------------------------------------------------------------------- // type class members @@ -1251,10 +1356,10 @@ const _wilt: Witherable1['wilt'] = ( export const of: Pointed1['of'] = NEA.of /** - * @category Alternative + * @category Zero * @since 2.7.0 */ -export const zero: Alternative1['zero'] = () => [] +export const zero: Zero1['zero'] = () => [] /** * `map` can be used to turn functions `(a: A) => B` into functions `(fa: F) => F` whose argument and return types @@ -1310,7 +1415,7 @@ export const filterMapWithIndex = (f: (i: number, a: A) => Option) => ( const out: Array = [] for (let i = 0; i < fa.length; i++) { const optionB = f(i, fa[i]) - if (O.isSome(optionB)) { + if (_.isSome(optionB)) { out.push(optionB.value) } } @@ -1354,18 +1459,20 @@ export const separate = (fa: Array>): Separated, Arr * @since 2.0.0 */ export const filter: { - (refinement: Refinement): (fa: Array) => Array - (predicate: Predicate): (fa: Array) => Array -} = (predicate: Predicate) => (fa: Array) => fa.filter(predicate) + (refinement: Refinement): (as: Array) => Array + (predicate: Predicate): (bs: Array) => Array + (predicate: Predicate): (as: Array) => Array +} = (predicate: Predicate) => (as: Array) => as.filter(predicate) /** * @category Filterable * @since 2.0.0 */ export const partition: { - (refinement: Refinement): (fa: Array) => Separated, Array> - (predicate: Predicate): (fa: Array) => Separated, Array> -} = (predicate: Predicate): ((fa: Array) => Separated, Array>) => + (refinement: Refinement): (as: Array) => Separated, Array> + (predicate: Predicate): (bs: Array) => Separated, Array> + (predicate: Predicate): (as: Array) => Separated, Array> +} = (predicate: Predicate): ((as: Array) => Separated, Array>) => partitionWithIndex((_, a) => predicate(a)) /** @@ -1374,18 +1481,19 @@ export const partition: { */ export const partitionWithIndex: { (refinementWithIndex: RefinementWithIndex): ( - fa: Array + as: Array ) => Separated, Array> - (predicateWithIndex: PredicateWithIndex): (fa: Array) => Separated, Array> -} = (predicateWithIndex: PredicateWithIndex) => (fa: Array): Separated, Array> => { + (predicateWithIndex: PredicateWithIndex): (bs: Array) => Separated, Array> + (predicateWithIndex: PredicateWithIndex): (as: Array) => Separated, Array> +} = (predicateWithIndex: PredicateWithIndex) => (as: Array): Separated, Array> => { const left: Array = [] const right: Array = [] - for (let i = 0; i < fa.length; i++) { - const a = fa[i] - if (predicateWithIndex(i, a)) { - right.push(a) + for (let i = 0; i < as.length; i++) { + const b = as[i] + if (predicateWithIndex(i, b)) { + right.push(b) } else { - left.push(a) + left.push(b) } } return separated(left, right) @@ -1441,16 +1549,17 @@ export const alt: (that: Lazy>) => (fa: Array) => Array = altW * @since 2.0.0 */ export const filterWithIndex: { - (refinementWithIndex: RefinementWithIndex): (fa: Array) => Array - (predicateWithIndex: PredicateWithIndex): (fa: Array) => Array -} = (predicateWithIndex: PredicateWithIndex) => (fa: Array): Array => - fa.filter((a, i) => predicateWithIndex(i, a)) + (refinementWithIndex: RefinementWithIndex): (as: Array) => Array + (predicateWithIndex: PredicateWithIndex): (bs: Array) => Array + (predicateWithIndex: PredicateWithIndex): (as: Array) => Array +} = (predicateWithIndex: PredicateWithIndex) => (as: Array): Array => + as.filter((b, i) => predicateWithIndex(i, b)) /** * @category Extend * @since 2.0.0 */ -export const extend: (f: (fa: Array) => B) => (wa: Array) => Array = (f) => (wa) => +export const extend: (f: (as: Array) => B) => (as: Array) => Array = (f) => (wa) => wa.map((_, i) => f(wa.slice(i))) /** @@ -1548,8 +1657,8 @@ export const traverseWithIndex: PipeableTraverseWithIndex1 = (F: export const wither: PipeableWither1 = ( F: ApplicativeHKT ): ((f: (a: A) => HKT>) => (fa: Array) => HKT>) => { - const traverseF = traverse(F) - return (f) => (fa) => F.map(pipe(fa, traverseF(f)), compact) + const _witherF = _wither(F) + return (f) => (fa) => _witherF(fa, f) } /** @@ -1559,11 +1668,22 @@ export const wither: PipeableWither1 = ( export const wilt: PipeableWilt1 = ( F: ApplicativeHKT ): ((f: (a: A) => HKT>) => (fa: Array) => HKT, Array>>) => { - const traverseF = traverse(F) - return (f) => (fa) => F.map(pipe(fa, traverseF(f)), separate) + const _wiltF = _wilt(F) + return (f) => (fa) => _wiltF(fa, f) } /** + * Creates an `Array` from the results of `f(b)`, where `b` is an initial value. + * `unfold` stops when `f` returns `Option.none`. + * @example + * import { unfold } from 'fp-ts/Array' + * import { some, none } from 'fp-ts/Option' + * + * assert.deepStrictEqual( + * unfold(5, (n) => (n > 0 ? some([n, n - 1]) : none)), + * [5, 4, 3, 2, 1] + * ) + * * @category Unfoldable * @since 2.6.6 */ @@ -1572,7 +1692,7 @@ export const unfold = (b: B, f: (b: B) => Option): Array< let bb: B = b while (true) { const mt = f(bb) - if (O.isSome(mt)) { + if (_.isSome(mt)) { const [a, b] = mt.value out.push(a) bb = b @@ -1674,6 +1794,48 @@ export const getEq: (E: Eq) => Eq> = RA.getEq */ export const getOrd: (O: Ord) => Ord> = RA.getOrd +/** + * @category instances + * @since 2.11.0 + */ +export const getUnionSemigroup = (E: Eq): Semigroup> => { + const unionE = union(E) + return { + concat: (first, second) => unionE(second)(first) + } +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getUnionMonoid = (E: Eq): Monoid> => ({ + concat: getUnionSemigroup(E).concat, + empty: [] +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const getIntersectionSemigroup = (E: Eq): Semigroup> => { + const intersectionE = intersection(E) + return { + concat: (first, second) => intersectionE(second)(first) + } +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getDifferenceMagma = (E: Eq): Magma> => { + const differenceE = difference(E) + return { + concat: (first, second) => differenceE(second)(first) + } +} + /** * @category instances * @since 2.7.0 @@ -1812,6 +1974,23 @@ export const Alt: Alt1 = { alt: _alt } +/** + * @category instances + * @since 2.11.0 + */ +export const Zero: Zero1 = { + URI, + zero +} + +/** + * @category constructors + * @since 2.11.0 + */ +export const guard = + /*#__PURE__*/ + guard_(Zero, Pointed) + /** * @category instances * @since 2.7.0 @@ -1938,6 +2117,9 @@ export const TraversableWithIndex: TraversableWithIndex1 = { traverseWithIndex: _traverseWithIndex } +const _wither: Witherable1['wither'] = witherDefault(Traversable, Compactable) +const _wilt: Witherable1['wilt'] = wiltDefault(Traversable, Compactable) + /** * @category instances * @since 2.7.0 @@ -1960,6 +2142,72 @@ export const Witherable: Witherable1 = { wilt: _wilt } +/** + * @category ChainRec + * @since 2.11.0 + */ +export const chainRecDepthFirst: ( + f: (a: A) => Array> +) => (a: A) => Array = RA.chainRecDepthFirst as any + +/** + * @category instances + * @since 2.11.0 + */ +export const ChainRecDepthFirst: ChainRec1 = { + URI, + map: _map, + ap: _ap, + chain: _chain, + chainRec: _chainRecDepthFirst +} + +/** + * @category ChainRec + * @since 2.11.0 + */ +export const chainRecBreadthFirst: ( + f: (a: A) => Array> +) => (a: A) => Array = RA.chainRecBreadthFirst as any + +/** + * @category instances + * @since 2.11.0 + */ +export const ChainRecBreadthFirst: ChainRec1 = { + URI, + map: _map, + ap: _ap, + chain: _chain, + chainRec: _chainRecBreadthFirst +} + +/** + * Filter values inside a context. + * + * @since 2.11.0 + */ +export const filterE = + /*#__PURE__*/ + filterE_(Witherable) + +/** + * @category instances + * @since 2.11.0 + */ +export const FromEither: FromEither1 = { + URI, + fromEither +} + +/** + * @category combinators + * @since 2.11.0 + */ +export const fromEitherK = + /*#__PURE__*/ + fromEitherK_(FromEither) + // ------------------------------------------------------------------------------------- // unsafe // ------------------------------------------------------------------------------------- @@ -2001,6 +2249,13 @@ export const every: (predicate: Predicate) => (as: Array) => boolean = */ export const some = (predicate: Predicate) => (as: Array): as is NonEmptyArray => as.some(predicate) +/** + * Alias of [`some`](#some) + * + * @since 2.11.0 + */ +export const exists = some + // ------------------------------------------------------------------------------------- // do notation // ------------------------------------------------------------------------------------- @@ -2010,7 +2265,7 @@ export const some = (predicate: Predicate) => (as: Array): as is NonEmp */ export const Do: Array<{}> = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 @@ -2041,6 +2296,17 @@ export const apS = // deprecated // ------------------------------------------------------------------------------------- +// tslint:disable: deprecation + +/** + * Use `NonEmptyArray` module instead. + * + * @category constructors + * @since 2.0.0 + * @deprecated + */ +export const range = NEA.range + /** * Use a new `[]` instead. * @@ -2056,7 +2322,6 @@ export const empty: Array = [] * @since 2.0.0 * @deprecated */ -// tslint:disable-next-line: deprecation export const cons = NEA.cons /** @@ -2066,7 +2331,6 @@ export const cons = NEA.cons * @since 2.0.0 * @deprecated */ -// tslint:disable-next-line: deprecation export const snoc = NEA.snoc /** diff --git a/src/Bounded.ts b/src/Bounded.ts index f61476823..7eb133c5c 100644 --- a/src/Bounded.ts +++ b/src/Bounded.ts @@ -26,6 +26,8 @@ export interface Bounded extends Ord { // deprecated // ------------------------------------------------------------------------------------- +// tslint:disable: deprecation + /** * Use [`Bounded`](./number.ts.html#bounded) instead. * @@ -34,9 +36,7 @@ export interface Bounded extends Ord { * @deprecated */ export const boundedNumber: Bounded = { - // tslint:disable-next-line: deprecation equals: ordNumber.equals, - // tslint:disable-next-line: deprecation compare: ordNumber.compare, top: Infinity, bottom: -Infinity diff --git a/src/Date.ts b/src/Date.ts index dc03bb3d1..95dfb449e 100644 --- a/src/Date.ts +++ b/src/Date.ts @@ -2,8 +2,10 @@ * @since 2.0.0 */ import * as E from './Eq' +import { pipe } from './function' import { IO } from './IO' import * as O from './Ord' +import * as N from './number' // ------------------------------------------------------------------------------------- // instances @@ -13,8 +15,9 @@ import * as O from './Ord' * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const Eq: E.Eq = E.eqDate +export const Eq: E.Eq = { + equals: (first, second) => first.valueOf() === second.valueOf() +} /** * @category instances @@ -49,8 +52,13 @@ export const eqYear: E.Eq = { * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const Ord: O.Ord = O.ordDate +export const Ord: O.Ord = + /*#__PURE__*/ + pipe( + N.Ord, + /*#__PURE__*/ + O.contramap((date) => date.valueOf()) + ) // ------------------------------------------------------------------------------------- // utils diff --git a/src/Either.ts b/src/Either.ts index 7ba08df40..a289d872d 100644 --- a/src/Either.ts +++ b/src/Either.ts @@ -30,21 +30,31 @@ import { Eq } from './Eq' import { Extend2 } from './Extend' import { Filterable2C } from './Filterable' import { Foldable2 } from './Foldable' -import { FromEither2 } from './FromEither' -import { flow, identity, Lazy, pipe, Predicate, Refinement } from './function' +import { + chainOptionK as chainOptionK_, + filterOrElse as filterOrElse_, + FromEither2, + fromOption as fromOption_, + fromOptionK as fromOptionK_, + fromPredicate as fromPredicate_ +} from './FromEither' +import { flow, identity, Lazy, pipe } from './function' import { bindTo as bindTo_, flap as flap_, Functor2 } from './Functor' import { HKT } from './HKT' import * as _ from './internal' import { Monad2, Monad2C } from './Monad' import { MonadThrow2, MonadThrow2C } from './MonadThrow' import { Monoid } from './Monoid' -import { Option } from './Option' +import { NonEmptyArray } from './NonEmptyArray' import { Pointed2 } from './Pointed' +import { Predicate } from './Predicate' +import { ReadonlyNonEmptyArray } from './ReadonlyNonEmptyArray' +import { Refinement } from './Refinement' import { Semigroup } from './Semigroup' import { Separated, separated } from './Separated' import { Show } from './Show' import { PipeableTraverse2, Traversable2 } from './Traversable' -import { Witherable2C } from './Witherable' +import { wiltDefault, Witherable2C, witherDefault } from './Witherable' // ------------------------------------------------------------------------------------- // model @@ -75,633 +85,415 @@ export interface Right { export type Either = Left | Right // ------------------------------------------------------------------------------------- -// guards +// constructors // ------------------------------------------------------------------------------------- /** - * Returns `true` if the either is an instance of `Left`, `false` otherwise. + * Constructs a new `Either` holding a `Left` value. This usually represents a failure, due to the right-bias of this + * structure. * - * @category guards + * @category constructors * @since 2.0.0 */ -export const isLeft: (ma: Either) => ma is Left = _.isLeft +export const left: (e: E) => Either = _.left /** - * Returns `true` if the either is an instance of `Right`, `false` otherwise. + * Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias + * of this structure. * - * @category guards + * @category constructors * @since 2.0.0 */ -export const isRight = (ma: Either): ma is Right => ma._tag === 'Right' +export const right: (a: A) => Either = _.right // ------------------------------------------------------------------------------------- -// constructors +// non-pipeables +// ------------------------------------------------------------------------------------- + +const _map: Monad2['map'] = (fa, f) => pipe(fa, map(f)) +const _ap: Monad2['ap'] = (fab, fa) => pipe(fab, ap(fa)) +/* istanbul ignore next */ +const _chain: Monad2['chain'] = (ma, f) => pipe(ma, chain(f)) +/* istanbul ignore next */ +const _reduce: Foldable2['reduce'] = (fa, b, f) => pipe(fa, reduce(b, f)) +/* istanbul ignore next */ +const _foldMap: Foldable2['foldMap'] = (M) => (fa, f) => { + const foldMapM = foldMap(M) + return pipe(fa, foldMapM(f)) +} +/* istanbul ignore next */ +const _reduceRight: Foldable2['reduceRight'] = (fa, b, f) => pipe(fa, reduceRight(b, f)) +const _traverse = ( + F: ApplicativeHKT +): ((ta: Either, f: (a: A) => HKT) => HKT>) => { + const traverseF = traverse(F) + return (ta, f) => pipe(ta, traverseF(f)) +} +const _bimap: Bifunctor2['bimap'] = (fa, f, g) => pipe(fa, bimap(f, g)) +const _mapLeft: Bifunctor2['mapLeft'] = (fa, f) => pipe(fa, mapLeft(f)) +/* istanbul ignore next */ +const _alt: Alt2['alt'] = (fa, that) => pipe(fa, alt(that)) +/* istanbul ignore next */ +const _extend: Extend2['extend'] = (wa, f) => pipe(wa, extend(f)) +const _chainRec: ChainRec2['chainRec'] = (a, f) => + tailRec(f(a), (e) => + isLeft(e) ? right(left(e.left)) : isLeft(e.right) ? left(f(e.right.left)) : right(right(e.right.right)) + ) + +// ------------------------------------------------------------------------------------- +// instances // ------------------------------------------------------------------------------------- /** - * Constructs a new `Either` holding a `Left` value. This usually represents a failure, due to the right-bias of this - * structure. - * - * @category constructors + * @category instances * @since 2.0.0 */ -export const left = (e: E): Either => ({ _tag: 'Left', left: e }) +export const URI = 'Either' /** - * Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias - * of this structure. - * - * @category constructors + * @category instances * @since 2.0.0 */ -export const right = (a: A): Either => ({ _tag: 'Right', right: a }) +export type URI = typeof URI + +declare module './HKT' { + interface URItoKind2 { + readonly [URI]: Either + } +} /** - * @example - * import { fromOption, left, right } from 'fp-ts/Either' - * import { pipe } from 'fp-ts/function' - * import { none, some } from 'fp-ts/Option' - * - * assert.deepStrictEqual( - * pipe( - * some(1), - * fromOption(() => 'error') - * ), - * right(1) - * ) - * assert.deepStrictEqual( - * pipe( - * none, - * fromOption(() => 'error') - * ), - * left('error') - * ) - * - * @category constructors + * @category instances * @since 2.0.0 */ -export const fromOption: (onNone: Lazy) => (ma: Option) => Either = (onNone) => (ma) => - ma._tag === 'None' ? left(onNone()) : right(ma.value) +export const getShow = (SE: Show, SA: Show): Show> => ({ + show: (ma) => (isLeft(ma) ? `left(${SE.show(ma.left)})` : `right(${SA.show(ma.right)})`) +}) /** - * @example - * import { fromPredicate, left, right } from 'fp-ts/Either' - * import { pipe } from 'fp-ts/function' - * - * assert.deepStrictEqual( - * pipe( - * 1, - * fromPredicate( - * (n) => n > 0, - * () => 'error' - * ) - * ), - * right(1) - * ) - * assert.deepStrictEqual( - * pipe( - * -1, - * fromPredicate( - * (n) => n > 0, - * () => 'error' - * ) - * ), - * left('error') - * ) - * - * @category constructors + * @category instances * @since 2.0.0 */ -export const fromPredicate: { - (refinement: Refinement, onFalse: (a: A) => E): (a: A) => Either - (predicate: Predicate, onFalse: (a: A) => E): (a: A) => Either -} = (predicate: Predicate, onFalse: (a: A) => E) => (a: A) => (predicate(a) ? right(a) : left(onFalse(a))) - -// ------------------------------------------------------------------------------------- -// destructors -// ------------------------------------------------------------------------------------- +export const getEq = (EL: Eq, EA: Eq): Eq> => ({ + equals: (x, y) => + x === y || (isLeft(x) ? isLeft(y) && EL.equals(x.left, y.left) : isRight(y) && EA.equals(x.right, y.right)) +}) /** - * Less strict version of [`match`](#match). + * Semigroup returning the left-most non-`Left` value. If both operands are `Right`s then the inner values are + * concatenated using the provided `Semigroup` * - * @category destructors - * @since 2.10.0 + * @example + * import { getSemigroup, left, right } from 'fp-ts/Either' + * import { SemigroupSum } from 'fp-ts/number' + * + * const S = getSemigroup(SemigroupSum) + * assert.deepStrictEqual(S.concat(left('a'), left('b')), left('a')) + * assert.deepStrictEqual(S.concat(left('a'), right(2)), right(2)) + * assert.deepStrictEqual(S.concat(right(1), left('b')), right(1)) + * assert.deepStrictEqual(S.concat(right(1), right(2)), right(3)) + * + * @category instances + * @since 2.0.0 */ -export const matchW = (onLeft: (e: E) => B, onRight: (a: A) => C) => (ma: Either): B | C => - isLeft(ma) ? onLeft(ma.left) : onRight(ma.right) +export const getSemigroup = (S: Semigroup): Semigroup> => ({ + concat: (x, y) => (isLeft(y) ? x : isLeft(x) ? y : right(S.concat(x.right, y.right))) +}) /** - * Alias of [`matchW`](#matchww). + * Builds a `Compactable` instance for `Either` given `Monoid` for the left side. * - * @category destructors + * @category instances * @since 2.10.0 */ -export const foldW = matchW +export const getCompactable = (M: Monoid): Compactable2C => { + const empty = left(M.empty) + return { + URI, + _E: undefined as any, + compact: (ma) => (isLeft(ma) ? ma : ma.right._tag === 'None' ? empty : right(ma.right.value)), + separate: (ma) => + isLeft(ma) + ? separated(ma, ma) + : isLeft(ma.right) + ? separated(right(ma.right.left), empty) + : separated(empty, right(ma.right.right)) + } +} /** - * Takes two functions and an `Either` value, if the value is a `Left` the inner value is applied to the first function, - * if the value is a `Right` the inner value is applied to the second function. - * - * @example - * import { match, left, right } from 'fp-ts/Either' - * import { pipe } from 'fp-ts/function' - * - * function onLeft(errors: Array): string { - * return `Errors: ${errors.join(', ')}` - * } - * - * function onRight(value: number): string { - * return `Ok: ${value}` - * } - * - * assert.strictEqual( - * pipe( - * right(1), - * match(onLeft, onRight) - * ), - * 'Ok: 1' - * ) - * assert.strictEqual( - * pipe( - * left(['error 1', 'error 2']), - * match(onLeft, onRight) - * ), - * 'Errors: error 1, error 2' - * ) + * Builds a `Filterable` instance for `Either` given `Monoid` for the left side * - * @category destructors + * @category instances * @since 2.10.0 */ -export const match: (onLeft: (e: E) => B, onRight: (a: A) => B) => (ma: Either) => B = matchW +export const getFilterable = (M: Monoid): Filterable2C => { + const empty = left(M.empty) + + const { compact, separate } = getCompactable(M) + + const filter = (ma: Either, predicate: Predicate): Either => + isLeft(ma) ? ma : predicate(ma.right) ? ma : empty + + const partition = (ma: Either, p: Predicate): Separated, Either> => { + return isLeft(ma) + ? separated(ma, ma) + : p(ma.right) + ? separated(empty, right(ma.right)) + : separated(right(ma.right), empty) + } + + return { + URI, + _E: undefined as any, + map: _map, + compact, + separate, + filter, + filterMap: (ma, f) => { + if (isLeft(ma)) { + return ma + } + const ob = f(ma.right) + return ob._tag === 'None' ? empty : right(ob.value) + }, + partition, + partitionMap: (ma, f) => { + if (isLeft(ma)) { + return separated(ma, ma) + } + const e = f(ma.right) + return isLeft(e) ? separated(right(e.left), empty) : separated(empty, right(e.right)) + } + } +} /** - * Alias of [`match`](#match). + * Builds `Witherable` instance for `Either` given `Monoid` for the left side * - * @category destructors + * @category instances * @since 2.0.0 */ -export const fold: (onLeft: (e: E) => B, onRight: (a: A) => B) => (ma: Either) => B = match +export const getWitherable = (M: Monoid): Witherable2C => { + const F_ = getFilterable(M) + const C = getCompactable(M) + return { + URI, + _E: undefined as any, + map: _map, + compact: F_.compact, + separate: F_.separate, + filter: F_.filter, + filterMap: F_.filterMap, + partition: F_.partition, + partitionMap: F_.partitionMap, + traverse: _traverse, + sequence, + reduce: _reduce, + foldMap: _foldMap, + reduceRight: _reduceRight, + wither: witherDefault(Traversable, C), + wilt: wiltDefault(Traversable, C) + } +} /** - * Less strict version of [`getOrElse`](#getorelse). - * - * @category destructors - * @since 2.6.0 + * @category instances + * @since 2.7.0 */ -export const getOrElseW = (onLeft: (e: E) => B) => (ma: Either): A | B => - isLeft(ma) ? onLeft(ma.left) : ma.right +export const getApplicativeValidation = (SE: Semigroup): Applicative2C => ({ + URI, + _E: undefined as any, + map: _map, + ap: (fab, fa) => + isLeft(fab) + ? isLeft(fa) + ? left(SE.concat(fab.left, fa.left)) + : fab + : isLeft(fa) + ? fa + : right(fab.right(fa.right)), + of +}) /** - * Returns the wrapped value if it's a `Right` or a default value if is a `Left`. - * - * @example - * import { getOrElse, left, right } from 'fp-ts/Either' - * import { pipe } from 'fp-ts/function' - * - * assert.deepStrictEqual( - * pipe( - * right(1), - * getOrElse(() => 0) - * ), - * 1 - * ) - * assert.deepStrictEqual( - * pipe( - * left('error'), - * getOrElse(() => 0) - * ), - * 0 - * ) - * - * @category destructors - * @since 2.0.0 + * @category instances + * @since 2.7.0 */ -export const getOrElse: (onLeft: (e: E) => A) => (ma: Either) => A = getOrElseW - -// ------------------------------------------------------------------------------------- -// interop -// ------------------------------------------------------------------------------------- +export const getAltValidation = (SE: Semigroup): Alt2C => ({ + URI, + _E: undefined as any, + map: _map, + alt: (me, that) => { + if (isRight(me)) { + return me + } + const ea = that() + return isLeft(ea) ? left(SE.concat(me.left, ea.left)) : ea + } +}) -// TODO: make lazy in v3 /** - * Takes a default and a nullable value, if the value is not nully, turn it into a `Right`, if the value is nully use - * the provided default as a `Left`. - * - * @example - * import { fromNullable, left, right } from 'fp-ts/Either' - * - * const parse = fromNullable('nully') - * - * assert.deepStrictEqual(parse(1), right(1)) - * assert.deepStrictEqual(parse(null), left('nully')) - * - * @category interop + * @category instance operations * @since 2.0.0 */ -export const fromNullable = (e: E) => (a: A): Either> => - a == null ? left(e) : right(a as NonNullable) +export const map: (f: (a: A) => B) => (fa: Either) => Either = (f) => (fa) => + isLeft(fa) ? fa : right(f(fa.right)) /** - * Constructs a new `Either` from a function that might throw. - * - * See also [`tryCatchK`](#trycatchk). - * - * @example - * import * as E from 'fp-ts/Either' - * - * const unsafeHead = (as: ReadonlyArray): A => { - * if (as.length > 0) { - * return as[0] - * } else { - * throw new Error('empty array') - * } - * } - * - * const head = (as: ReadonlyArray): E.Either => - * E.tryCatch(() => unsafeHead(as), e => (e instanceof Error ? e : new Error('unknown error'))) - * - * assert.deepStrictEqual(head([]), E.left(new Error('empty array'))) - * assert.deepStrictEqual(head([1, 2, 3]), E.right(1)) - * - * @category interop - * @since 2.0.0 + * @category instances + * @since 2.7.0 */ -export const tryCatch = (f: Lazy, onThrow: (e: unknown) => E): Either => { - try { - return right(f()) - } catch (e) { - return left(onThrow(e)) - } +export const Functor: Functor2 = { + URI, + map: _map } /** - * Converts a function that may throw to one returning a `Either`. - * - * @category interop - * @since 2.10.0 + * @category instance operations + * @since 2.7.0 */ -export const tryCatchK = , B, E>( - f: (...a: A) => B, - onThrow: (error: unknown) => E -): ((...a: A) => Either) => (...a) => tryCatch(() => f(...a), onThrow) +export const of: (a: A) => Either = right /** - * @category interop - * @since 2.9.0 + * @category instances + * @since 2.10.0 */ -export const fromNullableK = ( - e: E -): (, B>( - f: (...a: A) => B | null | undefined -) => (...a: A) => Either>) => { - const from = fromNullable(e) - return (f) => flow(f, from) +export const Pointed: Pointed2 = { + URI, + of } /** - * @category interop - * @since 2.9.0 + * Less strict version of [`ap`](#ap). + * + * @category instance operations + * @since 2.8.0 */ -export const chainNullableK = ( - e: E -): ((f: (a: A) => B | null | undefined) => (ma: Either) => Either>) => { - const from = fromNullableK(e) - return (f) => chain(from(f)) -} +export const apW: (fa: Either) => (fab: Either B>) => Either = (fa) => ( + fab +) => (isLeft(fab) ? fab : isLeft(fa) ? fa : right(fab.right(fa.right))) /** - * @category interop - * @since 2.10.0 + * Apply a function to an argument under a type constructor. + * + * @category instance operations + * @since 2.0.0 */ -export const toUnion: (fa: Either) => E | A = - /*#__PURE__*/ - foldW(identity, identity) - -// ------------------------------------------------------------------------------------- -// combinators -// ------------------------------------------------------------------------------------- +export const ap: (fa: Either) => (fab: Either B>) => Either = apW /** - * @category combinators + * @category instances * @since 2.10.0 */ -export const fromOptionK = ( - onNone: Lazy -): (, B>(f: (...a: A) => Option) => (...a: A) => Either) => { - const from = fromOption(onNone) - return (f) => flow(f, from) +export const Apply: Apply2 = { + URI, + map: _map, + ap: _ap } /** - * @category combinators - * @since 2.10.0 + * @category instances + * @since 2.7.0 */ -export const chainOptionK = ( - onNone: Lazy -): ((f: (a: A) => Option) => (ma: Either) => Either) => { - const from = fromOptionK(onNone) - return (f) => chain(from(f)) +export const Applicative: Applicative2 = { + URI, + map: _map, + ap: _ap, + of } /** - * Returns a `Right` if is a `Left` (and vice versa). + * Less strict version of [`chain`](#chain). * - * @category combinators - * @since 2.0.0 + * @category instance operations + * @since 2.6.0 */ -export function swap(ma: Either): Either { - return isLeft(ma) ? right(ma.left) : left(ma.right) -} +export const chainW = (f: (a: A) => Either) => (ma: Either): Either => + isLeft(ma) ? ma : f(ma.right) /** - * Less strict version of [`orElse`](#orelse). + * Composes computations in sequence, using the return value of one computation to determine the next computation. * - * @category combinators - * @since 2.10.0 + * @category instance operations + * @since 2.0.0 */ -export const orElseW = (onLeft: (e: E1) => Either) => (ma: Either): Either => - isLeft(ma) ? onLeft(ma.left) : ma +export const chain: (f: (a: A) => Either) => (ma: Either) => Either = chainW /** - * Useful for recovering from errors. - * - * @category combinators - * @since 2.0.0 + * @category instances + * @since 2.10.0 */ -export const orElse: (onLeft: (e: E1) => Either) => (ma: Either) => Either = orElseW +export const Chain: Chain2 = { + URI, + map: _map, + ap: _ap, + chain: _chain +} /** - * Less strict version of [`filterOrElse`](#filterorelse). - * - * @category combinators - * @since 2.9.0 + * @category instances + * @since 2.7.0 */ -export const filterOrElseW: { - (refinement: Refinement, onFalse: (a: A) => E2): ( - ma: Either - ) => Either - (predicate: Predicate, onFalse: (a: A) => E2): (ma: Either) => Either -} = (predicate: Predicate, onFalse: (a: A) => E2): ((ma: Either) => Either) => - chainW((a) => (predicate(a) ? right(a) : left(onFalse(a)))) +export const Monad: Monad2 = { + URI, + map: _map, + ap: _ap, + of, + chain: _chain +} /** + * Left-associative fold of a structure. + * * @example - * import { filterOrElse as filterOrElse, left, right } from 'fp-ts/Either' * import { pipe } from 'fp-ts/function' + * import * as E from 'fp-ts/Either' + * + * const startWith = 'prefix' + * const concat = (a: string, b: string) => `${a}:${b}` * * assert.deepStrictEqual( - * pipe( - * right(1), - * filterOrElse( - * (n) => n > 0, - * () => 'error' - * ) - * ), - * right(1) + * pipe(E.right('a'), E.reduce(startWith, concat)), + * 'prefix:a' * ) + * * assert.deepStrictEqual( - * pipe( - * right(-1), - * filterOrElse( - * (n) => n > 0, - * () => 'error' - * ) - * ), - * left('error') + * pipe(E.left('e'), E.reduce(startWith, concat)), + * 'prefix' + * ) + * + * @category instance operations + * @since 2.0.0 + */ +export const reduce: (b: B, f: (b: B, a: A) => B) => (fa: Either) => B = (b, f) => (fa) => + isLeft(fa) ? b : f(b, fa.right) + +/** + * Map each element of the structure to a monoid, and combine the results. + * + * @example + * import { pipe } from 'fp-ts/function' + * import * as E from 'fp-ts/Either' + * import * as S from 'fp-ts/string' + * + * const yell = (a: string) => `${a}!` + * + * assert.deepStrictEqual( + * pipe(E.right('a'), E.foldMap(S.Monoid)(yell)), + * 'a!' * ) + * * assert.deepStrictEqual( - * pipe( - * left('a'), - * filterOrElse( - * (n) => n > 0, - * () => 'error' - * ) - * ), - * left('a') + * pipe(E.left('e'), E.foldMap(S.Monoid)(yell)), + * S.Monoid.empty * ) * - * @category combinators + * @category instance operations * @since 2.0.0 */ -export const filterOrElse: { - (refinement: Refinement, onFalse: (a: A) => E): (ma: Either) => Either - (predicate: Predicate, onFalse: (a: A) => E): (ma: Either) => Either -} = filterOrElseW - -// ------------------------------------------------------------------------------------- -// non-pipeables -// ------------------------------------------------------------------------------------- - -const _map: Monad2['map'] = (fa, f) => pipe(fa, map(f)) -const _ap: Monad2['ap'] = (fab, fa) => pipe(fab, ap(fa)) -/* istanbul ignore next */ -const _chain: Monad2['chain'] = (ma, f) => pipe(ma, chain(f)) -/* istanbul ignore next */ -const _reduce: Foldable2['reduce'] = (fa, b, f) => pipe(fa, reduce(b, f)) -/* istanbul ignore next */ -const _foldMap: Foldable2['foldMap'] = (M) => (fa, f) => { - const foldMapM = foldMap(M) - return pipe(fa, foldMapM(f)) -} -/* istanbul ignore next */ -const _reduceRight: Foldable2['reduceRight'] = (fa, b, f) => pipe(fa, reduceRight(b, f)) -const _traverse = ( - F: ApplicativeHKT -): ((ta: Either, f: (a: A) => HKT) => HKT>) => { - const traverseF = traverse(F) - return (ta, f) => pipe(ta, traverseF(f)) -} -const _bimap: Bifunctor2['bimap'] = (fa, f, g) => pipe(fa, bimap(f, g)) -const _mapLeft: Bifunctor2['mapLeft'] = (fa, f) => pipe(fa, mapLeft(f)) -/* istanbul ignore next */ -const _alt: Alt2['alt'] = (fa, that) => pipe(fa, alt(that)) -/* istanbul ignore next */ -const _extend: Extend2['extend'] = (wa, f) => pipe(wa, extend(f)) -const _chainRec: ChainRec2['chainRec'] = (a, f) => - tailRec(f(a), (e) => - isLeft(e) ? right(left(e.left)) : isLeft(e.right) ? left(f(e.right.left)) : right(right(e.right.right)) - ) - -// ------------------------------------------------------------------------------------- -// type class members -// ------------------------------------------------------------------------------------- - -/** - * `map` can be used to turn functions `(a: A) => B` into functions `(fa: F) => F` whose argument and return types - * use the type constructor `F` to represent some computational context. - * - * @category Functor - * @since 2.0.0 - */ -export const map: (f: (a: A) => B) => (fa: Either) => Either = (f) => (fa) => - isLeft(fa) ? fa : right(f(fa.right)) - -/** - * Map a pair of functions over the two type arguments of the bifunctor. - * - * @category Bifunctor - * @since 2.0.0 - */ -export const bimap: (f: (e: E) => G, g: (a: A) => B) => (fa: Either) => Either = (f, g) => ( - fa -) => (isLeft(fa) ? left(f(fa.left)) : right(g(fa.right))) - -/** - * Map a function over the first type argument of a bifunctor. - * - * @category Bifunctor - * @since 2.0.0 - */ -export const mapLeft: (f: (e: E) => G) => (fa: Either) => Either = (f) => (fa) => - isLeft(fa) ? left(f(fa.left)) : fa - -/** - * Less strict version of [`ap`](#ap). - * - * @category Apply - * @since 2.8.0 - */ -export const apW: (fa: Either) => (fab: Either B>) => Either = (fa) => ( - fab -) => (isLeft(fab) ? fab : isLeft(fa) ? fa : right(fab.right(fa.right))) - -/** - * Apply a function to an argument under a type constructor. - * - * @category Apply - * @since 2.0.0 - */ -export const ap: (fa: Either) => (fab: Either B>) => Either = apW - -/** - * @category Pointed - * @since 2.7.0 - */ -export const of: (a: A) => Either = right - -/** - * Less strict version of [`chain`](#chain). - * - * @category Monad - * @since 2.6.0 - */ -export const chainW = (f: (a: A) => Either) => (ma: Either): Either => - isLeft(ma) ? ma : f(ma.right) - -/** - * Composes computations in sequence, using the return value of one computation to determine the next computation. - * - * @category Monad - * @since 2.0.0 - */ -export const chain: (f: (a: A) => Either) => (ma: Either) => Either = chainW - -/** - * The `flatten` function is the conventional monad join operator. It is used to remove one level of monadic structure, projecting its bound argument into the outer level. - * - * Derivable from `Chain`. - * - * @example - * import * as E from 'fp-ts/Either' - * - * assert.deepStrictEqual(E.flatten(E.right(E.right('a'))), E.right('a')) - * assert.deepStrictEqual(E.flatten(E.right(E.left('e'))), E.left('e')) - * assert.deepStrictEqual(E.flatten(E.left('e')), E.left('e')) - * - * @category combinators - * @since 2.0.0 - */ -export const flatten: (mma: Either>) => Either = - /*#__PURE__*/ - chain(identity) - -/** - * Less strict version of [`alt`](#alt). - * - * @category Alt - * @since 2.9.0 - */ -export const altW: (that: Lazy>) => (fa: Either) => Either = (that) => ( - fa -) => (isLeft(fa) ? that() : fa) - -/** - * Identifies an associative operation on a type constructor. It is similar to `Semigroup`, except that it applies to - * types of kind `* -> *`. - * - * @category Alt - * @since 2.0.0 - */ -export const alt: (that: Lazy>) => (fa: Either) => Either = altW - -/** - * @category Extend - * @since 2.0.0 - */ -export const extend: (f: (wa: Either) => B) => (wa: Either) => Either = (f) => (wa) => - isLeft(wa) ? wa : right(f(wa)) - -/** - * Derivable from `Extend`. - * - * @category combinators - * @since 2.0.0 - */ -export const duplicate: (ma: Either) => Either> = - /*#__PURE__*/ - extend(identity) - -/** - * Left-associative fold of a structure. - * - * @example - * import { pipe } from 'fp-ts/function' - * import * as E from 'fp-ts/Either' - * - * const startWith = 'prefix' - * const concat = (a: string, b: string) => `${a}:${b}` - * - * assert.deepStrictEqual( - * pipe(E.right('a'), E.reduce(startWith, concat)), - * 'prefix:a' - * ) - * - * assert.deepStrictEqual( - * pipe(E.left('e'), E.reduce(startWith, concat)), - * 'prefix' - * ) - * - * @category Foldable - * @since 2.0.0 - */ -export const reduce: (b: B, f: (b: B, a: A) => B) => (fa: Either) => B = (b, f) => (fa) => - isLeft(fa) ? b : f(b, fa.right) - -/** - * Map each element of the structure to a monoid, and combine the results. - * - * @example - * import { pipe } from 'fp-ts/function' - * import * as E from 'fp-ts/Either' - * import * as S from 'fp-ts/string' - * - * const yell = (a: string) => `${a}!` - * - * assert.deepStrictEqual( - * pipe(E.right('a'), E.foldMap(S.Monoid)(yell)), - * 'a!' - * ) - * - * assert.deepStrictEqual( - * pipe(E.left('e'), E.foldMap(S.Monoid)(yell)), - * S.Monoid.empty - * ) - * - * @category Foldable - * @since 2.0.0 - */ -export const foldMap: (M: Monoid) => (f: (a: A) => M) => (fa: Either) => M = (M) => (f) => (fa) => - isLeft(fa) ? M.empty : f(fa.right) +export const foldMap: (M: Monoid) => (f: (a: A) => M) => (fa: Either) => M = (M) => (f) => (fa) => + isLeft(fa) ? M.empty : f(fa.right) /** * Right-associative fold of a structure. @@ -723,12 +515,23 @@ export const foldMap: (M: Monoid) => (f: (a: A) => M) => (fa: Either * 'postfix' * ) * - * @category Foldable + * @category instance operations * @since 2.0.0 */ export const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: Either) => B = (b, f) => (fa) => isLeft(fa) ? b : f(fa.right, b) +/** + * @category instances + * @since 2.7.0 + */ +export const Foldable: Foldable2 = { + URI, + reduce: _reduce, + foldMap: _foldMap, + reduceRight: _reduceRight +} + /** * Map each element of a structure to an action, evaluate these actions from left to right, and collect the results. * @@ -748,7 +551,7 @@ export const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: Either = (F: ApplicativeHKT) => (f: (a: A) => HKT) => ( @@ -773,7 +576,7 @@ export const traverse: PipeableTraverse2 = (F: ApplicativeHKT) => ['sequence'] = (F: ApplicativeHKT) => ( @@ -782,269 +585,334 @@ export const sequence: Traversable2['sequence'] = (F: ApplicativeHKT) return isLeft(ma) ? F.of(left(ma.left)) : F.map>(ma.right, right) } -/** - * @category MonadThrow - * @since 2.6.3 - */ -export const throwError: MonadThrow2['throwError'] = left - -// ------------------------------------------------------------------------------------- -// instances -// ------------------------------------------------------------------------------------- - /** * @category instances - * @since 2.0.0 + * @since 2.7.0 */ -export const URI = 'Either' +export const Traversable: Traversable2 = { + URI, + map: _map, + reduce: _reduce, + foldMap: _foldMap, + reduceRight: _reduceRight, + traverse: _traverse, + sequence +} /** - * @category instances + * Map a pair of functions over the two type arguments of the bifunctor. + * + * @category instance operations * @since 2.0.0 */ -export type URI = typeof URI - -declare module './HKT' { - interface URItoKind2 { - readonly [URI]: Either - } -} +export const bimap: (f: (e: E) => G, g: (a: A) => B) => (fa: Either) => Either = (f, g) => ( + fa +) => (isLeft(fa) ? left(f(fa.left)) : right(g(fa.right))) /** - * @category instances + * Map a function over the first type argument of a bifunctor. + * + * @category instance operations * @since 2.0.0 */ -export function getShow(SE: Show, SA: Show): Show> { - return { - show: (ma) => (isLeft(ma) ? `left(${SE.show(ma.left)})` : `right(${SA.show(ma.right)})`) - } -} +export const mapLeft: (f: (e: E) => G) => (fa: Either) => Either = (f) => (fa) => + isLeft(fa) ? left(f(fa.left)) : fa /** * @category instances - * @since 2.0.0 + * @since 2.7.0 */ -export function getEq(EL: Eq, EA: Eq): Eq> { - return { - equals: (x, y) => - x === y || (isLeft(x) ? isLeft(y) && EL.equals(x.left, y.left) : isRight(y) && EA.equals(x.right, y.right)) - } +export const Bifunctor: Bifunctor2 = { + URI, + bimap: _bimap, + mapLeft: _mapLeft } /** - * Semigroup returning the left-most non-`Left` value. If both operands are `Right`s then the inner values are - * concatenated using the provided `Semigroup` - * - * @example - * import { getSemigroup, left, right } from 'fp-ts/Either' - * import { SemigroupSum } from 'fp-ts/number' - * - * const S = getSemigroup(SemigroupSum) - * assert.deepStrictEqual(S.concat(left('a'), left('b')), left('a')) - * assert.deepStrictEqual(S.concat(left('a'), right(2)), right(2)) - * assert.deepStrictEqual(S.concat(right(1), left('b')), right(1)) - * assert.deepStrictEqual(S.concat(right(1), right(2)), right(3)) + * Less strict version of [`alt`](#alt). * - * @category instances - * @since 2.0.0 + * @category instance operations + * @since 2.9.0 */ -export function getSemigroup(S: Semigroup): Semigroup> { - return { - concat: (x, y) => (isLeft(y) ? x : isLeft(x) ? y : right(S.concat(x.right, y.right))) - } -} +export const altW: (that: Lazy>) => (fa: Either) => Either = (that) => ( + fa +) => (isLeft(fa) ? that() : fa) /** - * Builds a `Compactable` instance for `Either` given `Monoid` for the left side. + * Identifies an associative operation on a type constructor. It is similar to `Semigroup`, except that it applies to + * types of kind `* -> *`. * - * @category instances - * @since 2.10.0 + * @category instance operations + * @since 2.0.0 */ -export const getCompactable = (M: Monoid): Compactable2C => { - const empty = left(M.empty) - return { - URI, - _E: undefined as any, - compact: (ma) => (isLeft(ma) ? ma : ma.right._tag === 'None' ? empty : right(ma.right.value)), - separate: (ma) => - isLeft(ma) - ? separated(ma, ma) - : isLeft(ma.right) - ? separated(right(ma.right.left), empty) - : separated(empty, right(ma.right.right)) - } -} +export const alt: (that: Lazy>) => (fa: Either) => Either = altW /** - * Builds a `Filterable` instance for `Either` given `Monoid` for the left side - * * @category instances - * @since 2.10.0 + * @since 2.7.0 */ -export function getFilterable(M: Monoid): Filterable2C { - const empty = left(M.empty) - - const { compact, separate } = getCompactable(M) - - const filter = (ma: Either, predicate: Predicate): Either => - isLeft(ma) ? ma : predicate(ma.right) ? ma : empty - - const partition = (ma: Either, p: Predicate): Separated, Either> => { - return isLeft(ma) - ? separated(ma, ma) - : p(ma.right) - ? separated(empty, right(ma.right)) - : separated(right(ma.right), empty) - } - - return { - URI, - _E: undefined as any, - map: _map, - compact, - separate, - filter, - filterMap: (ma, f) => { - if (isLeft(ma)) { - return ma - } - const ob = f(ma.right) - return ob._tag === 'None' ? empty : right(ob.value) - }, - partition, - partitionMap: (ma, f) => { - if (isLeft(ma)) { - return separated(ma, ma) - } - const e = f(ma.right) - return isLeft(e) ? separated(right(e.left), empty) : separated(empty, right(e.right)) - } - } +export const Alt: Alt2 = { + URI, + map: _map, + alt: _alt } /** - * Builds `Witherable` instance for `Either` given `Monoid` for the left side - * - * @category instances + * @category instance operations * @since 2.0.0 */ -export function getWitherable(M: Monoid): Witherable2C { - const F_ = getFilterable(M) - - const wither = ( - F: ApplicativeHKT - ): ((ma: Either, f: (a: A) => HKT>) => HKT>) => { - const traverseF = _traverse(F) - return (ma, f) => F.map(traverseF(ma, f), F_.compact) - } - - const wilt = ( - F: ApplicativeHKT - ): (( - ma: Either, - f: (a: A) => HKT> - ) => HKT, Either>>) => { - const traverseF = _traverse(F) - return (ma, f) => F.map(traverseF(ma, f), F_.separate) - } +export const extend: (f: (wa: Either) => B) => (wa: Either) => Either = (f) => (wa) => + isLeft(wa) ? wa : right(f(wa)) - return { - URI, - _E: undefined as any, - map: _map, - compact: F_.compact, - separate: F_.separate, - filter: F_.filter, - filterMap: F_.filterMap, - partition: F_.partition, - partitionMap: F_.partitionMap, - traverse: _traverse, - sequence, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight, - wither, - wilt - } +/** + * @category instances + * @since 2.7.0 + */ +export const Extend: Extend2 = { + URI, + map: _map, + extend: _extend } /** * @category instances * @since 2.7.0 */ -export function getApplicativeValidation(SE: Semigroup): Applicative2C { - return { - URI, - _E: undefined as any, - map: _map, - ap: (fab, fa) => - isLeft(fab) - ? isLeft(fa) - ? left(SE.concat(fab.left, fa.left)) - : fab - : isLeft(fa) - ? fa - : right(fab.right(fa.right)), - of - } +export const ChainRec: ChainRec2 = { + URI, + map: _map, + ap: _ap, + chain: _chain, + chainRec: _chainRec } +/** + * @category instance operations + * @since 2.6.3 + */ +export const throwError: MonadThrow2['throwError'] = left + /** * @category instances * @since 2.7.0 */ -export function getAltValidation(SE: Semigroup): Alt2C { - return { - URI, - _E: undefined as any, - map: _map, - alt: (me, that) => { - if (isRight(me)) { - return me - } - const ea = that() - return isLeft(ea) ? left(SE.concat(me.left, ea.left)) : ea - } - } +export const MonadThrow: MonadThrow2 = { + URI, + map: _map, + ap: _ap, + of, + chain: _chain, + throwError } /** * @category instances - * @since 2.7.0 + * @since 2.10.0 */ -export const Functor: Functor2 = { +export const FromEither: FromEither2 = { URI, - map: _map + fromEither: identity } /** - * Derivable from `Functor`. + * @example + * import { fromPredicate, left, right } from 'fp-ts/Either' + * import { pipe } from 'fp-ts/function' * - * @category combinators + * assert.deepStrictEqual( + * pipe( + * 1, + * fromPredicate( + * (n) => n > 0, + * () => 'error' + * ) + * ), + * right(1) + * ) + * assert.deepStrictEqual( + * pipe( + * -1, + * fromPredicate( + * (n) => n > 0, + * () => 'error' + * ) + * ), + * left('error') + * ) + * + * @category constructors + * @since 2.0.0 + */ +export const fromPredicate = + /*#__PURE__*/ + fromPredicate_(FromEither) + +// ------------------------------------------------------------------------------------- +// natural transformations +// ------------------------------------------------------------------------------------- + +/** + * @example + * import * as E from 'fp-ts/Either' + * import { pipe } from 'fp-ts/function' + * import * as O from 'fp-ts/Option' + * + * assert.deepStrictEqual( + * pipe( + * O.some(1), + * E.fromOption(() => 'error') + * ), + * E.right(1) + * ) + * assert.deepStrictEqual( + * pipe( + * O.none, + * E.fromOption(() => 'error') + * ), + * E.left('error') + * ) + * + * @category natural transformations + * @since 2.0.0 + */ +export const fromOption = + /*#__PURE__*/ + fromOption_(FromEither) + +// ------------------------------------------------------------------------------------- +// refinements +// ------------------------------------------------------------------------------------- + +/** + * Returns `true` if the either is an instance of `Left`, `false` otherwise. + * + * @category refinements + * @since 2.0.0 + */ +export const isLeft: (ma: Either) => ma is Left = _.isLeft + +/** + * Returns `true` if the either is an instance of `Right`, `false` otherwise. + * + * @category refinements + * @since 2.0.0 + */ +export const isRight: (ma: Either) => ma is Right = _.isRight + +// ------------------------------------------------------------------------------------- +// destructors +// ------------------------------------------------------------------------------------- + +/** + * Less strict version of [`match`](#match). + * + * @category destructors * @since 2.10.0 */ -export const flap = - /*#_PURE_*/ - flap_(Functor) +export const matchW = (onLeft: (e: E) => B, onRight: (a: A) => C) => (ma: Either): B | C => + isLeft(ma) ? onLeft(ma.left) : onRight(ma.right) /** - * @category instances + * Alias of [`matchW`](#matchw). + * + * @category destructors * @since 2.10.0 */ -export const Pointed: Pointed2 = { - URI, - of -} +export const foldW = matchW /** - * @category instances + * Takes two functions and an `Either` value, if the value is a `Left` the inner value is applied to the first function, + * if the value is a `Right` the inner value is applied to the second function. + * + * @example + * import { match, left, right } from 'fp-ts/Either' + * import { pipe } from 'fp-ts/function' + * + * function onLeft(errors: Array): string { + * return `Errors: ${errors.join(', ')}` + * } + * + * function onRight(value: number): string { + * return `Ok: ${value}` + * } + * + * assert.strictEqual( + * pipe( + * right(1), + * match(onLeft, onRight) + * ), + * 'Ok: 1' + * ) + * assert.strictEqual( + * pipe( + * left(['error 1', 'error 2']), + * match(onLeft, onRight) + * ), + * 'Errors: error 1, error 2' + * ) + * + * @category destructors * @since 2.10.0 */ -export const Apply: Apply2 = { - URI, - map: _map, - ap: _ap -} +export const match: (onLeft: (e: E) => B, onRight: (a: A) => B) => (ma: Either) => B = matchW + +/** + * Alias of [`match`](#match). + * + * @category destructors + * @since 2.0.0 + */ +export const fold: (onLeft: (e: E) => B, onRight: (a: A) => B) => (ma: Either) => B = match + +/** + * Less strict version of [`getOrElse`](#getorelse). + * + * @category destructors + * @since 2.6.0 + */ +export const getOrElseW = (onLeft: (e: E) => B) => (ma: Either): A | B => + isLeft(ma) ? onLeft(ma.left) : ma.right + +/** + * Returns the wrapped value if it's a `Right` or a default value if is a `Left`. + * + * @example + * import { getOrElse, left, right } from 'fp-ts/Either' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual( + * pipe( + * right(1), + * getOrElse(() => 0) + * ), + * 1 + * ) + * assert.deepStrictEqual( + * pipe( + * left('error'), + * getOrElse(() => 0) + * ), + * 0 + * ) + * + * @category destructors + * @since 2.0.0 + */ +export const getOrElse: (onLeft: (e: E) => A) => (ma: Either) => A = getOrElseW + +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- + +/** + * Derivable from `Functor`. + * + * @category combinators + * @since 2.10.0 + */ +export const flap = + /*#_PURE_*/ + flap_(Functor) /** * Combine two effectful actions, keeping only the result of the first. @@ -1066,157 +934,267 @@ export const apFirst = * @category combinators * @since 2.0.0 */ -export const apSecond = - /*#__PURE__*/ - apSecond_(Apply) +export const apSecond = + /*#__PURE__*/ + apSecond_(Apply) + +/** + * Composes computations in sequence, using the return value of one computation to determine the next computation and + * keeping only the result of the first. + * + * Derivable from `Chain`. + * + * @category combinators + * @since 2.0.0 + */ +export const chainFirst: (f: (a: A) => Either) => (ma: Either) => Either = + /*#__PURE__*/ + chainFirst_(Chain) + +/** + * Less strict version of [`chainFirst`](#chainfirst) + * + * Derivable from `Chain`. + * + * @category combinators + * @since 2.8.0 + */ +export const chainFirstW: ( + f: (a: A) => Either +) => (ma: Either) => Either = chainFirst as any + +/** + * Less strict version of [`flatten`](#flatten). + * + * @category combinators + * @since 2.11.0 + */ +export const flattenW: (mma: Either>) => Either = + /*#__PURE__*/ + chainW(identity) + +/** + * The `flatten` function is the conventional monad join operator. It is used to remove one level of monadic structure, projecting its bound argument into the outer level. + * + * Derivable from `Chain`. + * + * @example + * import * as E from 'fp-ts/Either' + * + * assert.deepStrictEqual(E.flatten(E.right(E.right('a'))), E.right('a')) + * assert.deepStrictEqual(E.flatten(E.right(E.left('e'))), E.left('e')) + * assert.deepStrictEqual(E.flatten(E.left('e')), E.left('e')) + * + * @category combinators + * @since 2.0.0 + */ +export const flatten: (mma: Either>) => Either = flattenW /** - * @category instances - * @since 2.7.0 + * Derivable from `Extend`. + * + * @category combinators + * @since 2.0.0 */ -export const Applicative: Applicative2 = { - URI, - map: _map, - ap: _ap, - of -} +export const duplicate: (ma: Either) => Either> = + /*#__PURE__*/ + extend(identity) /** - * @category instances + * @category combinators * @since 2.10.0 */ -export const Chain: Chain2 = { - URI, - map: _map, - ap: _ap, - chain: _chain -} +export const fromOptionK = + /*#__PURE__*/ + fromOptionK_(FromEither) /** - * @category instances - * @since 2.7.0 + * @category combinators + * @since 2.11.0 */ -export const Monad: Monad2 = { - URI, - map: _map, - ap: _ap, - of, - chain: _chain -} +export const chainOptionK = + /*#__PURE__*/ + chainOptionK_(FromEither, Chain) /** - * Composes computations in sequence, using the return value of one computation to determine the next computation and - * keeping only the result of the first. + * @example + * import * as E from 'fp-ts/Either' + * import { pipe } from 'fp-ts/function' * - * Derivable from `Chain`. + * assert.deepStrictEqual( + * pipe( + * E.right(1), + * E.filterOrElse( + * (n) => n > 0, + * () => 'error' + * ) + * ), + * E.right(1) + * ) + * assert.deepStrictEqual( + * pipe( + * E.right(-1), + * E.filterOrElse( + * (n) => n > 0, + * () => 'error' + * ) + * ), + * E.left('error') + * ) + * assert.deepStrictEqual( + * pipe( + * E.left('a'), + * E.filterOrElse( + * (n) => n > 0, + * () => 'error' + * ) + * ), + * E.left('a') + * ) * * @category combinators * @since 2.0.0 */ -export const chainFirst: (f: (a: A) => Either) => (ma: Either) => Either = +export const filterOrElse = /*#__PURE__*/ - chainFirst_(Chain) + filterOrElse_(FromEither, Chain) /** - * Less strict version of [`chainFirst`](#chainfirst) + * Less strict version of [`filterOrElse`](#filterorelse). * - * Derivable from `Chain`. + * @category combinators + * @since 2.9.0 + */ +export const filterOrElseW: { + (refinement: Refinement, onFalse: (a: A) => E2): ( + ma: Either + ) => Either + (predicate: Predicate, onFalse: (a: A) => E2): (mb: Either) => Either + (predicate: Predicate, onFalse: (a: A) => E2): (ma: Either) => Either +} = filterOrElse + +/** + * Returns a `Right` if is a `Left` (and vice versa). * * @category combinators - * @since 2.8.0 + * @since 2.0.0 */ -export const chainFirstW: ( - f: (a: A) => Either -) => (ma: Either) => Either = chainFirst as any +export const swap = (ma: Either): Either => (isLeft(ma) ? right(ma.left) : left(ma.right)) /** - * @category instances - * @since 2.7.0 + * Less strict version of [`orElse`](#orelse). + * + * @category combinators + * @since 2.10.0 */ -export const Foldable: Foldable2 = { - URI, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight -} +export const orElseW = (onLeft: (e: E1) => Either) => (ma: Either): Either => + isLeft(ma) ? onLeft(ma.left) : ma /** - * @category instances - * @since 2.7.0 + * Useful for recovering from errors. + * + * @category combinators + * @since 2.0.0 */ -export const Traversable: Traversable2 = { - URI, - map: _map, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight, - traverse: _traverse, - sequence -} +export const orElse: (onLeft: (e: E1) => Either) => (ma: Either) => Either = orElseW + +// ------------------------------------------------------------------------------------- +// interop +// ------------------------------------------------------------------------------------- /** - * @category instances - * @since 2.7.0 + * Takes a default and a nullable value, if the value is not nully, turn it into a `Right`, if the value is nully use + * the provided default as a `Left`. + * + * @example + * import { fromNullable, left, right } from 'fp-ts/Either' + * + * const parse = fromNullable('nully') + * + * assert.deepStrictEqual(parse(1), right(1)) + * assert.deepStrictEqual(parse(null), left('nully')) + * + * @category interop + * @since 2.0.0 */ -export const Bifunctor: Bifunctor2 = { - URI, - bimap: _bimap, - mapLeft: _mapLeft -} +export const fromNullable = (e: E) => (a: A): Either> => + a == null ? left(e) : right(a as NonNullable) /** - * @category instances - * @since 2.7.0 + * Constructs a new `Either` from a function that might throw. + * + * See also [`tryCatchK`](#trycatchk). + * + * @example + * import * as E from 'fp-ts/Either' + * + * const unsafeHead = (as: ReadonlyArray): A => { + * if (as.length > 0) { + * return as[0] + * } else { + * throw new Error('empty array') + * } + * } + * + * const head = (as: ReadonlyArray): E.Either => + * E.tryCatch(() => unsafeHead(as), e => (e instanceof Error ? e : new Error('unknown error'))) + * + * assert.deepStrictEqual(head([]), E.left(new Error('empty array'))) + * assert.deepStrictEqual(head([1, 2, 3]), E.right(1)) + * + * @category interop + * @since 2.0.0 */ -export const Alt: Alt2 = { - URI, - map: _map, - alt: _alt +export const tryCatch = (f: Lazy, onThrow: (e: unknown) => E): Either => { + try { + return right(f()) + } catch (e) { + return left(onThrow(e)) + } } /** - * @category instances - * @since 2.7.0 + * Converts a function that may throw to one returning a `Either`. + * + * @category interop + * @since 2.10.0 */ -export const Extend: Extend2 = { - URI, - map: _map, - extend: _extend -} +export const tryCatchK = , B, E>( + f: (...a: A) => B, + onThrow: (error: unknown) => E +): ((...a: A) => Either) => (...a) => tryCatch(() => f(...a), onThrow) /** - * @category instances - * @since 2.7.0 + * @category interop + * @since 2.9.0 */ -export const ChainRec: ChainRec2 = { - URI, - map: _map, - ap: _ap, - chain: _chain, - chainRec: _chainRec +export const fromNullableK = ( + e: E +): (, B>( + f: (...a: A) => B | null | undefined +) => (...a: A) => Either>) => { + const from = fromNullable(e) + return (f) => flow(f, from) } /** - * @category instances - * @since 2.7.0 + * @category interop + * @since 2.9.0 */ -export const MonadThrow: MonadThrow2 = { - URI, - map: _map, - ap: _ap, - of, - chain: _chain, - throwError +export const chainNullableK = ( + e: E +): ((f: (a: A) => B | null | undefined) => (ma: Either) => Either>) => { + const from = fromNullableK(e) + return (f) => chain(from(f)) } /** - * @category instances + * @category interop * @since 2.10.0 */ -export const FromEither: FromEither2 = { - URI, - fromEither: identity -} +export const toUnion: (fa: Either) => E | A = + /*#__PURE__*/ + foldW(identity, identity) // ------------------------------------------------------------------------------------- // utils @@ -1234,9 +1212,8 @@ export function toError(e: unknown): Error { /** * @since 2.0.0 */ -export function elem(E: Eq): (a: A, ma: Either) => boolean { - return (a, ma) => (isLeft(ma) ? false : E.equals(a, ma.right)) -} +export const elem = (E: Eq) => (a: A, ma: Either): boolean => + isLeft(ma) ? false : E.equals(a, ma.right) /** * Returns `false` if `Left` or returns the result of the application of the given predicate to the `Right` value. @@ -1252,9 +1229,8 @@ export function elem(E: Eq): (a: A, ma: Either) => boolean { * * @since 2.0.0 */ -export function exists(predicate: Predicate): (ma: Either) => boolean { - return (ma) => (isLeft(ma) ? false : predicate(ma.right)) -} +export const exists = (predicate: Predicate) => (ma: Either): boolean => + isLeft(ma) ? false : predicate(ma.right) // ------------------------------------------------------------------------------------- // do notation @@ -1265,7 +1241,7 @@ export function exists(predicate: Predicate): (ma: Either) => boo */ export const Do: Either = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 @@ -1312,20 +1288,33 @@ export const apSW: ( fa: Either ) => Either = apS as any +// ------------------------------------------------------------------------------------- +// sequence T +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export const ApT: Either = of(_.emptyReadonlyArray) + // ------------------------------------------------------------------------------------- // array utils // ------------------------------------------------------------------------------------- /** - * Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. * - * @since 2.9.0 + * @since 2.11.0 */ -export const traverseArrayWithIndex = (f: (index: number, a: A) => Either) => ( - as: ReadonlyArray -): Either> => { - const out = [] - for (let i = 0; i < as.length; i++) { +export const traverseReadonlyNonEmptyArrayWithIndex = (f: (index: number, a: A) => Either) => ( + as: ReadonlyNonEmptyArray +): Either> => { + const e = f(0, _.head(as)) + if (isLeft(e)) { + return e + } + const out: NonEmptyArray = [e.right] + for (let i = 1; i < as.length; i++) { const e = f(i, as[i]) if (isLeft(e)) { return e @@ -1336,17 +1325,32 @@ export const traverseArrayWithIndex = (f: (index: number, a: A) => Eith } /** - * Equivalent to `ReadonlyArray#traverse(Applicative)`. + * Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndex = ( + f: (index: number, a: A) => Either +): ((as: ReadonlyArray) => Either>) => { + const g = traverseReadonlyNonEmptyArrayWithIndex(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + +/** + * @since 2.9.0 + */ +export const traverseArrayWithIndex: ( + f: (index: number, a: A) => Either +) => (as: ReadonlyArray) => Either> = traverseReadonlyArrayWithIndex + +/** * @since 2.9.0 */ export const traverseArray = ( f: (a: A) => Either -): ((as: ReadonlyArray) => Either>) => traverseArrayWithIndex((_, a) => f(a)) +): ((as: ReadonlyArray) => Either>) => traverseReadonlyArrayWithIndex((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(Applicative)`. - * * @since 2.9.0 */ export const sequenceArray: (as: ReadonlyArray>) => Either> = @@ -1357,13 +1361,14 @@ export const sequenceArray: (as: ReadonlyArray>) => Either {} /** @@ -1393,7 +1396,6 @@ export interface JsonArray extends ReadonlyArray {} * @since 2.0.0 * @deprecated */ -// tslint:disable-next-line: deprecation export function parseJSON(s: string, onError: (reason: unknown) => E): Either { return tryCatch(() => JSON.parse(s), onError) } diff --git a/src/EitherT.ts b/src/EitherT.ts index 8e26b44f4..ee50350e4 100644 --- a/src/EitherT.ts +++ b/src/EitherT.ts @@ -332,7 +332,7 @@ export function altValidation( // ------------------------------------------------------------------------------------- /** - * @since 3.0.0 + * @since 2.11.0 */ export function match( F: Functor3 @@ -466,6 +466,82 @@ export function orElse( return (onLeft) => (ma) => M.chain(ma, (e) => (E.isLeft(e) ? onLeft(e.left) : M.of(e))) } +/** + * @since 2.11.0 + */ +export function orElseFirst( + M: Monad3 +): ( + onLeft: (e: E) => Kind3> +) => (ma: Kind3>) => Kind3> +export function orElseFirst( + M: Monad3C +): ( + onLeft: (e: E) => Kind3> +) => (ma: Kind3>) => Kind3> +export function orElseFirst( + M: Monad2 +): ( + onLeft: (e: E) => Kind2> +) => (ma: Kind2>) => Kind2> +export function orElseFirst( + M: Monad2C +): ( + onLeft: (e: E) => Kind2> +) => (ma: Kind2>) => Kind2> +export function orElseFirst( + M: Monad1 +): (onLeft: (e: E) => Kind>) => (ma: Kind>) => Kind> +export function orElseFirst( + M: Monad +): (onLeft: (e: E) => HKT>) => (ma: HKT>) => HKT> +export function orElseFirst( + M: Monad +): (onLeft: (e: E) => HKT>) => (ma: HKT>) => HKT> { + const orElseM = orElse(M) + return (onLeft) => orElseM((e) => M.map(onLeft(e), (eb) => (E.isLeft(eb) ? eb : E.left(e)))) +} + +/** + * @since 2.11.0 + */ +export function orLeft( + M: Monad3 +): ( + onLeft: (e: E1) => Kind3 +) => (fa: Kind3>) => Kind3> +export function orLeft( + M: Monad3C +): ( + onLeft: (e: E1) => Kind3 +) => (fa: Kind3>) => Kind3> +export function orLeft( + M: Monad2 +): ( + onLeft: (e: E1) => Kind2 +) => (fa: Kind2>) => Kind2> +export function orLeft( + M: Monad2C +): (onLeft: (e: E1) => Kind2) => (fa: Kind2>) => Kind2> +export function orLeft( + M: Monad1 +): (onLeft: (e: E1) => Kind) => (fa: Kind>) => Kind> +export function orLeft( + M: Monad +): (onLeft: (e: E1) => HKT) => (fa: HKT>) => HKT> +export function orLeft( + M: Monad +): (onLeft: (e: E1) => HKT) => (fa: HKT>) => HKT> { + return (onLeft) => (ma) => + M.chain( + ma, + E.match( + (e) => M.map(onLeft(e), E.left), + (a) => M.of(E.right(a)) + ) + ) +} + // ------------------------------------------------------------------------------------- // utils // ------------------------------------------------------------------------------------- diff --git a/src/Endomorphism.ts b/src/Endomorphism.ts new file mode 100644 index 000000000..23872c53d --- /dev/null +++ b/src/Endomorphism.ts @@ -0,0 +1,65 @@ +/** + * @since 2.11.0 + */ + +import { flow, identity } from './function' +import { Monoid } from './Monoid' +import { Semigroup } from './Semigroup' + +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export interface Endomorphism { + (a: A): A +} + +// ------------------------------------------------------------------------------------- +// instances +// ------------------------------------------------------------------------------------- + +// ------------------------------------------------------------------------------------- +// instances +// ------------------------------------------------------------------------------------- + +/** + * @category instances + * @since 2.11.0 + */ +export const URI = 'Endomorphism' + +/** + * @category instances + * @since 2.11.0 + */ +export type URI = typeof URI + +declare module './HKT' { + interface URItoKind { + readonly [URI]: Endomorphism + } +} + +/** + * Endomorphism form a `Semigroup` where the `concat` operation is the usual function composition. + * + * @category instances + * @since 2.11.0 + */ +export const getSemigroup = (): Semigroup> => ({ + concat: (first, second) => flow(first, second) +}) + +/** + * Endomorphism form a `Monoid` where the `empty` value is the `identity` function. + * + * @category instances + * @since 2.11.0 + */ +export const getMonoid = (): Monoid> => ({ + concat: getSemigroup().concat, + empty: identity +}) diff --git a/src/Eq.ts b/src/Eq.ts index 581b51909..d176a86eb 100644 --- a/src/Eq.ts +++ b/src/Eq.ts @@ -35,11 +35,9 @@ export interface Eq { * @category constructors * @since 2.0.0 */ -export function fromEquals(equals: Eq['equals']): Eq { - return { - equals: (x, y) => x === y || equals(x, y) - } -} +export const fromEquals = (equals: Eq['equals']): Eq => ({ + equals: (x, y) => x === y || equals(x, y) +}) // ------------------------------------------------------------------------------------- // combinators diff --git a/src/Filterable.ts b/src/Filterable.ts index 7642f788a..3ac0b6a0d 100644 --- a/src/Filterable.ts +++ b/src/Filterable.ts @@ -6,6 +6,7 @@ * @since 2.0.0 */ import { + compact, Compactable, Compactable1, Compactable2, @@ -20,11 +21,10 @@ import { CompactableComposition21, CompactableComposition22, CompactableComposition23, - compact, separate } from './Compactable' import { Either } from './Either' -import { pipe, Predicate, Refinement } from './function' +import { pipe } from './function' import { Functor, Functor1, @@ -44,6 +44,8 @@ import { } from './Functor' import { HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT' import { getLeft, getRight, Option } from './Option' +import { not, Predicate } from './Predicate' +import { Refinement } from './Refinement' import { separated, Separated } from './Separated' // ------------------------------------------------------------------------------------- @@ -288,19 +290,35 @@ export interface Filterable4 extends Functor4, Compactable4< export function filter( F: Functor2, G: Filterable2C -): (predicate: Predicate) => (fga: Kind2>) => Kind2> +): { + (refinement: Refinement): (fga: Kind2>) => Kind2> + (predicate: Predicate): (fgb: Kind2>) => Kind2> + (predicate: Predicate): (fga: Kind2>) => Kind2> +} export function filter( F: Functor1, G: Filterable2C -): (predicate: Predicate) => (fga: Kind>) => Kind> +): { + (refinement: Refinement): (fga: Kind>) => Kind> + (predicate: Predicate): (fgb: Kind>) => Kind> + (predicate: Predicate): (fga: Kind>) => Kind> +} export function filter( F: Functor1, G: Filterable1 -): (predicate: Predicate) => (fga: Kind>) => Kind> +): { + (refinement: Refinement): (fga: Kind>) => Kind> + (predicate: Predicate): (fgb: Kind>) => Kind> + (predicate: Predicate): (fga: Kind>) => Kind> +} export function filter( F: Functor, G: Filterable -): (predicate: Predicate) => (fga: HKT>) => HKT> +): { + (refinement: Refinement): (fga: HKT>) => HKT> + (predicate: Predicate): (fgb: HKT>) => HKT> + (predicate: Predicate): (fga: HKT>) => HKT> +} export function filter( F: Functor, G: Filterable @@ -346,36 +364,63 @@ export function filterMap( export function partition( F: Functor2, G: Filterable2C -): ( - predicate: Predicate -) => (fga: Kind2>) => Separated>, Kind2>> +): { + (refinement: Refinement): ( + fga: Kind2> + ) => Separated>, Kind2>> + (predicate: Predicate): ( + fgb: Kind2> + ) => Separated>, Kind2>> + (predicate: Predicate): ( + fga: Kind2> + ) => Separated>, Kind2>> +} export function partition( F: Functor1, G: Filterable2C -): ( - predicate: Predicate -) => (fga: Kind>) => Separated>, Kind>> +): { + (refinement: Refinement): ( + fga: Kind> + ) => Separated>, Kind>> + (predicate: Predicate): ( + fgb: Kind> + ) => Separated>, Kind>> + (predicate: Predicate): ( + fga: Kind> + ) => Separated>, Kind>> +} export function partition( F: Functor1, G: Filterable1 -): (predicate: Predicate) => (fga: Kind>) => Separated>, Kind>> +): { + (refinement: Refinement): ( + fga: Kind> + ) => Separated>, Kind>> + (predicate: Predicate): ( + fgb: Kind> + ) => Separated>, Kind>> + (predicate: Predicate): (fga: Kind>) => Separated>, Kind>> +} export function partition( F: Functor, G: Filterable -): (predicate: Predicate) => (fga: HKT>) => Separated>, HKT>> +): { + (refinement: Refinement): ( + fga: HKT> + ) => Separated>, HKT>> + (predicate: Predicate): (fgb: HKT>) => Separated>, HKT>> + (predicate: Predicate): (fga: HKT>) => Separated>, HKT>> +} export function partition( F: Functor, G: Filterable ): (predicate: Predicate) => (fga: HKT>) => Separated>, HKT>> { const _filter = filter(F, G) - return (predicate) => (fga) => - separated( - pipe( - fga, - _filter((a) => !predicate(a)) - ), - pipe(fga, _filter(predicate)) - ) + return (predicate) => { + const left = _filter(not(predicate)) + const right = _filter(predicate) + return (fgb) => separated(left(fgb), right(fgb)) + } } /** diff --git a/src/FromEither.ts b/src/FromEither.ts index b14bdee1f..4b10fdbf8 100644 --- a/src/FromEither.ts +++ b/src/FromEither.ts @@ -4,13 +4,25 @@ * @since 2.10.0 */ -import { Chain, Chain2, Chain2C, Chain3, Chain3C, Chain4 } from './Chain' -import * as E from './Either' -import { flow, Lazy, Predicate, Refinement } from './function' -import { HKT2, Kind2, Kind3, Kind4, URIS2, URIS3, URIS4 } from './HKT' -import { Option } from './Option' - -import Either = E.Either +import { Chain, Chain1, Chain2, Chain2C, Chain3, Chain3C, Chain4 } from './Chain' +import { Either, URI as EURI } from './Either' +import { flow, Lazy } from './function' +import { HKT2, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT' +import * as _ from './internal' +import { + NaturalTransformation12C, + NaturalTransformation13C, + NaturalTransformation14C, + NaturalTransformation21, + NaturalTransformation22, + NaturalTransformation22C, + NaturalTransformation23, + NaturalTransformation23C, + NaturalTransformation24 +} from './NaturalTransformation' +import { Option, URI as OURI } from './Option' +import { Predicate } from './Predicate' +import { Refinement } from './Refinement' // ------------------------------------------------------------------------------------- // model @@ -25,13 +37,22 @@ export interface FromEither { readonly fromEither: (e: Either) => HKT2 } +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromEither1 { + readonly URI: F + readonly fromEither: NaturalTransformation21 +} + /** * @category type classes * @since 2.10.0 */ export interface FromEither2 { readonly URI: F - readonly fromEither: (e: Either) => Kind2 + readonly fromEither: NaturalTransformation22 } /** @@ -41,7 +62,7 @@ export interface FromEither2 { export interface FromEither2C { readonly URI: F readonly _E: E - readonly fromEither: (e: Either) => Kind2 + readonly fromEither: NaturalTransformation22C } /** @@ -50,7 +71,7 @@ export interface FromEither2C { */ export interface FromEither3 { readonly URI: F - readonly fromEither: (e: Either) => Kind3 + readonly fromEither: NaturalTransformation23 } /** @@ -60,7 +81,7 @@ export interface FromEither3 { export interface FromEither3C { readonly URI: F readonly _E: E - readonly fromEither: (e: Either) => Kind3 + readonly fromEither: NaturalTransformation23C } /** @@ -69,7 +90,7 @@ export interface FromEither3C { */ export interface FromEither4 { readonly URI: F - readonly fromEither: (e: Either) => Kind4 + readonly fromEither: NaturalTransformation24 } // ------------------------------------------------------------------------------------- @@ -77,75 +98,84 @@ export interface FromEither4 { // ------------------------------------------------------------------------------------- /** + * @category constructors * @since 2.10.0 */ export function fromOption( F: FromEither4 -): (onNone: Lazy) => (ma: Option) => Kind4 +): (onNone: Lazy) => NaturalTransformation14C export function fromOption( F: FromEither3 -): (onNone: Lazy) => (ma: Option) => Kind3 +): (onNone: Lazy) => NaturalTransformation13C export function fromOption( F: FromEither3C -): (onNone: Lazy) => (ma: Option) => Kind3 +): (onNone: Lazy) => NaturalTransformation13C export function fromOption( F: FromEither2 -): (onNone: Lazy) => (ma: Option) => Kind2 +): (onNone: Lazy) => NaturalTransformation12C export function fromOption( F: FromEither2C -): (onNone: Lazy) => (ma: Option) => Kind2 +): (onNone: Lazy) => NaturalTransformation12C export function fromOption(F: FromEither): (onNone: Lazy) => (ma: Option) => HKT2 export function fromOption(F: FromEither): (onNone: Lazy) => (ma: Option) => HKT2 { - return (onNone) => flow(E.fromOption(onNone), F.fromEither) + return (onNone) => (ma) => F.fromEither(_.isNone(ma) ? _.left(onNone()) : _.right(ma.value)) } /** + * @category constructors * @since 2.10.0 */ export function fromPredicate( F: FromEither4 ): { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => Kind4 + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => Kind4 (predicate: Predicate, onFalse: (a: A) => E): (a: A) => Kind4 } export function fromPredicate( F: FromEither3 ): { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => Kind3 + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => Kind3 (predicate: Predicate, onFalse: (a: A) => E): (a: A) => Kind3 } export function fromPredicate( F: FromEither3C ): { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => Kind3 + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => Kind3 (predicate: Predicate, onFalse: (a: A) => E): (a: A) => Kind3 } export function fromPredicate( F: FromEither2 ): { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => Kind2 + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => Kind2 (predicate: Predicate, onFalse: (a: A) => E): (a: A) => Kind2 } export function fromPredicate( F: FromEither2C ): { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => Kind2 + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => Kind2 (predicate: Predicate, onFalse: (a: A) => E): (a: A) => Kind2 } export function fromPredicate( F: FromEither ): { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => HKT2 + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => HKT2 (predicate: Predicate, onFalse: (a: A) => E): (a: A) => HKT2 } export function fromPredicate( F: FromEither ): { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => HKT2 + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => HKT2 (predicate: Predicate, onFalse: (a: A) => E): (a: A) => HKT2 } { - return (predicate: Predicate, onFalse: (a: A) => E) => - flow(E.fromPredicate(predicate, onFalse), F.fromEither) + return (predicate: Predicate, onFalse: (a: A) => E) => (a: A) => + F.fromEither(predicate(a) ? _.right(a) : _.left(onFalse(a))) } // ------------------------------------------------------------------------------------- @@ -153,6 +183,7 @@ export function fromPredicate( // ------------------------------------------------------------------------------------- /** + * @category combinators * @since 2.10.0 */ export function fromOptionK( @@ -196,6 +227,7 @@ export function fromOptionK( } /** + * @category combinators * @since 2.10.0 */ export function chainOptionK( @@ -234,6 +266,7 @@ export function chainOptionK( } /** + * @category combinators * @since 2.10.0 */ export function fromEitherK( @@ -251,6 +284,9 @@ export function fromEitherK( export function fromEitherK( F: FromEither2C ): , B>(f: (...a: A) => Either) => (...a: A) => Kind2 +export function fromEitherK( + F: FromEither1 +): , B>(f: (...a: A) => Either) => (...a: A) => Kind export function fromEitherK( F: FromEither ): , E, B>(f: (...a: A) => Either) => (...a: A) => HKT2 @@ -261,6 +297,7 @@ export function fromEitherK( } /** + * @category combinators * @since 2.10.0 */ export function chainEitherK( @@ -283,6 +320,10 @@ export function chainEitherK( F: FromEither2C, M: Chain2C ): (f: (a: A) => Either) => (ma: Kind2) => Kind2 +export function chainEitherK( + F: FromEither1, + M: Chain1 +): (f: (a: A) => Either) => (ma: Kind) => Kind export function chainEitherK( F: FromEither, M: Chain @@ -296,6 +337,7 @@ export function chainEitherK( } /** + * @category combinators * @since 2.10.0 */ export function filterOrElse( @@ -305,6 +347,9 @@ export function filterOrElse( (refinement: Refinement, onFalse: (a: A) => E): ( ma: Kind4 ) => Kind4 + (predicate: Predicate, onFalse: (a: A) => E): ( + mb: Kind4 + ) => Kind4 (predicate: Predicate, onFalse: (a: A) => E): (ma: Kind4) => Kind4 } export function filterOrElse( @@ -314,6 +359,7 @@ export function filterOrElse( (refinement: Refinement, onFalse: (a: A) => E): ( ma: Kind3 ) => Kind3 + (predicate: Predicate, onFalse: (a: A) => E): (mb: Kind3) => Kind3 (predicate: Predicate, onFalse: (a: A) => E): (ma: Kind3) => Kind3 } export function filterOrElse( @@ -321,6 +367,7 @@ export function filterOrElse( M: Chain3C ): { (refinement: Refinement, onFalse: (a: A) => E): (ma: Kind3) => Kind3 + (predicate: Predicate, onFalse: (a: A) => E): (mb: Kind3) => Kind3 (predicate: Predicate, onFalse: (a: A) => E): (ma: Kind3) => Kind3 } export function filterOrElse( @@ -328,6 +375,7 @@ export function filterOrElse( M: Chain2 ): { (refinement: Refinement, onFalse: (a: A) => E): (ma: Kind2) => Kind2 + (predicate: Predicate, onFalse: (a: A) => E): (mb: Kind2) => Kind2 (predicate: Predicate, onFalse: (a: A) => E): (ma: Kind2) => Kind2 } export function filterOrElse( @@ -335,6 +383,7 @@ export function filterOrElse( M: Chain2C ): { (refinement: Refinement, onFalse: (a: A) => E): (ma: Kind2) => Kind2 + (predicate: Predicate, onFalse: (a: A) => E): (mb: Kind2) => Kind2 (predicate: Predicate, onFalse: (a: A) => E): (ma: Kind2) => Kind2 } export function filterOrElse( @@ -342,6 +391,7 @@ export function filterOrElse( M: Chain ): { (refinement: Refinement, onFalse: (a: A) => E): (ma: HKT2) => HKT2 + (predicate: Predicate, onFalse: (a: A) => E): (mb: HKT2) => HKT2 (predicate: Predicate, onFalse: (a: A) => E): (ma: HKT2) => HKT2 } export function filterOrElse( @@ -349,8 +399,9 @@ export function filterOrElse( M: Chain2 ): { (refinement: Refinement, onFalse: (a: A) => E): (ma: Kind2) => Kind2 + (predicate: Predicate, onFalse: (a: A) => E): (mb: Kind2) => Kind2 (predicate: Predicate, onFalse: (a: A) => E): (ma: Kind2) => Kind2 } { - return (predicate: Predicate, onFalse: (a: A) => E) => (ma: Kind2): Kind2 => - M.chain(ma, flow(E.fromPredicate(predicate, onFalse), F.fromEither)) + return (predicate: Predicate, onFalse: (a: A) => E) => (ma: Kind2): Kind2 => + M.chain(ma, (a) => F.fromEither(predicate(a) ? _.right(a) : _.left(onFalse(a)))) } diff --git a/src/FromIO.ts b/src/FromIO.ts index 3517a510e..a3482d857 100644 --- a/src/FromIO.ts +++ b/src/FromIO.ts @@ -6,7 +6,15 @@ import { Chain, Chain1, Chain2, Chain2C, Chain3, Chain3C, Chain4, chainFirst } from './Chain' import { flow } from './function' import { HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT' -import { IO } from './IO' +import { IO, URI } from './IO' +import { + NaturalTransformation11, + NaturalTransformation12, + NaturalTransformation12C, + NaturalTransformation13, + NaturalTransformation13C, + NaturalTransformation14 +} from './NaturalTransformation' // ------------------------------------------------------------------------------------- // model @@ -27,7 +35,7 @@ export interface FromIO { */ export interface FromIO1 { readonly URI: F - readonly fromIO: (fa: IO) => Kind + readonly fromIO: NaturalTransformation11 } /** @@ -36,7 +44,7 @@ export interface FromIO1 { */ export interface FromIO2 { readonly URI: F - readonly fromIO: (fa: IO) => Kind2 + readonly fromIO: NaturalTransformation12 } /** @@ -46,7 +54,7 @@ export interface FromIO2 { export interface FromIO2C { readonly URI: F readonly _E: E - readonly fromIO: (fa: IO) => Kind2 + readonly fromIO: NaturalTransformation12C } /** @@ -55,7 +63,7 @@ export interface FromIO2C { */ export interface FromIO3 { readonly URI: F - readonly fromIO: (fa: IO) => Kind3 + readonly fromIO: NaturalTransformation13 } /** @@ -65,7 +73,7 @@ export interface FromIO3 { export interface FromIO3C { readonly URI: F readonly _E: E - readonly fromIO: (fa: IO) => Kind3 + readonly fromIO: NaturalTransformation13C } /** @@ -74,7 +82,7 @@ export interface FromIO3C { */ export interface FromIO4 { readonly URI: F - readonly fromIO: (fa: IO) => Kind4 + readonly fromIO: NaturalTransformation14 } // ------------------------------------------------------------------------------------- diff --git a/src/FromReader.ts b/src/FromReader.ts new file mode 100644 index 000000000..e02a44394 --- /dev/null +++ b/src/FromReader.ts @@ -0,0 +1,189 @@ +/** + * Lift a computation from the `Reader` monad. + * + * @since 2.11.0 + */ +import { Chain, Chain2, Chain3, Chain3C, Chain4, chainFirst } from './Chain' +import { flow } from './function' +import { HKT2, Kind2, Kind3, Kind4, URIS2, URIS3, URIS4 } from './HKT' +import { + NaturalTransformation22, + NaturalTransformation23R, + NaturalTransformation23RC, + NaturalTransformation24R +} from './NaturalTransformation' +import * as R from './Reader' + +import Reader = R.Reader + +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromReader { + readonly URI: F + readonly fromReader: (fa: Reader) => HKT2 +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromReader2 { + readonly URI: F + readonly fromReader: NaturalTransformation22 +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromReader3 { + readonly URI: F + readonly fromReader: NaturalTransformation23R +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromReader3C { + readonly URI: F + readonly _E: E + readonly fromReader: NaturalTransformation23RC +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromReader4 { + readonly URI: F + readonly fromReader: NaturalTransformation24R +} + +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- + +/** + * @category constructors + * @since 2.11.0 + */ +export function ask(F: FromReader4): () => Kind4 +export function ask(F: FromReader3): () => Kind3 +export function ask(F: FromReader3C): () => Kind3 +export function ask(F: FromReader2): () => Kind2 +export function ask(F: FromReader): () => HKT2 +export function ask(F: FromReader): () => HKT2 { + return () => F.fromReader(R.ask()) +} + +/** + * @category constructors + * @since 2.11.0 + */ +export function asks(F: FromReader4): (f: (r: R) => A) => Kind4 +export function asks(F: FromReader3): (f: (r: R) => A) => Kind3 +export function asks(F: FromReader3C): (f: (r: R) => A) => Kind3 +export function asks(F: FromReader2): (f: (r: R) => A) => Kind2 +export function asks(F: FromReader): (f: (r: R) => A) => HKT2 +export function asks(F: FromReader): (f: (r: R) => A) => HKT2 { + return F.fromReader +} + +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- + +/** + * @category combinators + * @since 2.11.0 + */ +export function fromReaderK( + F: FromReader4 +): , R, B>(f: (...a: A) => Reader) => (...a: A) => Kind4 +export function fromReaderK( + F: FromReader3 +): , R, B>(f: (...a: A) => Reader) => (...a: A) => Kind3 +export function fromReaderK( + F: FromReader3C +): , R, B>(f: (...a: A) => Reader) => (...a: A) => Kind3 +export function fromReaderK( + F: FromReader2 +): , R, B>(f: (...a: A) => Reader) => (...a: A) => Kind2 +export function fromReaderK( + F: FromReader +): , R, B>(f: (...a: A) => Reader) => (...a: A) => HKT2 +export function fromReaderK( + F: FromReader +): , R, B>(f: (...a: A) => Reader) => (...a: A) => HKT2 { + return (f) => flow(f, F.fromReader) +} + +/** + * @category combinators + * @since 2.11.0 + */ +export function chainReaderK( + F: FromReader4, + M: Chain4 +): (f: (a: A) => Reader) => (ma: Kind4) => Kind4 +export function chainReaderK( + F: FromReader3, + M: Chain3 +): (f: (a: A) => Reader) => (ma: Kind3) => Kind3 +export function chainReaderK( + F: FromReader3C, + M: Chain3C +): (f: (a: A) => Reader) => (ma: Kind3) => Kind3 +export function chainReaderK( + F: FromReader2, + M: Chain2 +): (f: (a: A) => Reader) => (ma: Kind2) => Kind2 +export function chainReaderK( + F: FromReader, + M: Chain +): (f: (a: A) => Reader) => (ma: HKT2) => HKT2 +export function chainReaderK( + F: FromReader2, + M: Chain2 +): (f: (a: A) => Reader) => (ma: Kind2) => Kind2 { + const fromReaderKF = fromReaderK(F) + return (f) => (ma) => M.chain(ma, fromReaderKF(f)) +} + +/** + * @category combinators + * @since 2.11.0 + */ +export function chainFirstReaderK( + F: FromReader4, + M: Chain4 +): (f: (a: A) => Reader) => (ma: Kind4) => Kind4 +export function chainFirstReaderK( + F: FromReader3, + M: Chain3 +): (f: (a: A) => Reader) => (ma: Kind3) => Kind3 +export function chainFirstReaderK( + F: FromReader3C, + M: Chain3C +): (f: (a: A) => Reader) => (ma: Kind3) => Kind3 +export function chainFirstReaderK( + F: FromReader2, + M: Chain2 +): (f: (a: A) => Reader) => (ma: Kind2) => Kind2 +export function chainFirstReaderK( + F: FromReader, + M: Chain +): (f: (a: A) => Reader) => (ma: HKT2) => HKT2 +export function chainFirstReaderK( + F: FromReader2, + M: Chain2 +): (f: (a: A) => Reader) => (ma: Kind2) => Kind2 { + return flow(fromReaderK(F), chainFirst(M)) +} diff --git a/src/FromState.ts b/src/FromState.ts new file mode 100644 index 000000000..6b00ae916 --- /dev/null +++ b/src/FromState.ts @@ -0,0 +1,181 @@ +/** + * Lift a computation from the `State` monad. + * + * @since 2.11.0 + */ +import { Chain, Chain2, Chain3, Chain4 } from './Chain' +import { Endomorphism } from './Endomorphism' +import { flow } from './function' +import { HKT2, Kind2, Kind3, Kind4, URIS2, URIS3, URIS4 } from './HKT' +import { + NaturalTransformation22, + NaturalTransformation23R, + NaturalTransformation23RC, + NaturalTransformation24S +} from './NaturalTransformation' +import * as S from './State' + +import State = S.State + +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromState { + readonly URI: F + readonly fromState: (fa: State) => HKT2 +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromState2 { + readonly URI: F + readonly fromState: NaturalTransformation22 +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromState3 { + readonly URI: F + readonly fromState: NaturalTransformation23R +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromState3C { + readonly URI: F + readonly _E: E + readonly fromState: NaturalTransformation23RC +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromState4 { + readonly URI: F + readonly fromState: NaturalTransformation24S +} + +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- + +/** + * @category constructors + * @since 2.11.0 + */ +export function get(F: FromState4): () => Kind4 +export function get(F: FromState3): () => Kind3 +export function get(F: FromState3C): () => Kind3 +export function get(F: FromState2): () => Kind2 +export function get(F: FromState): () => HKT2 +export function get(F: FromState): () => HKT2 { + return () => F.fromState(S.get()) +} + +/** + * @category constructors + * @since 2.11.0 + */ +export function put(F: FromState4): (s: S) => Kind4 +export function put(F: FromState3): (s: S) => Kind3 +export function put(F: FromState3C): (s: S) => Kind3 +export function put(F: FromState2): (s: S) => Kind2 +export function put(F: FromState): (s: S) => HKT2 +export function put(F: FromState): (s: S) => HKT2 { + return (s) => F.fromState(S.put(s)) +} + +/** + * @category constructors + * @since 2.11.0 + */ +export function modify(F: FromState4): (f: Endomorphism) => Kind4 +export function modify(F: FromState3): (f: Endomorphism) => Kind3 +export function modify(F: FromState3C): (f: Endomorphism) => Kind3 +export function modify(F: FromState2): (f: Endomorphism) => Kind2 +export function modify(F: FromState): (f: Endomorphism) => HKT2 +export function modify(F: FromState): (f: Endomorphism) => HKT2 { + return flow(S.modify, F.fromState) +} + +/** + * @category constructors + * @since 2.11.0 + */ +export function gets(F: FromState4): (f: (s: S) => A) => Kind4 +export function gets(F: FromState3): (f: (s: S) => A) => Kind3 +export function gets(F: FromState3C): (f: (s: S) => A) => Kind3 +export function gets(F: FromState2): (f: (s: S) => A) => Kind2 +export function gets(F: FromState): (f: (s: S) => A) => HKT2 +export function gets(F: FromState): (f: (s: S) => A) => HKT2 { + return flow(S.gets, F.fromState) +} + +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- + +/** + * @category combinators + * @since 2.11.0 + */ +export function fromStateK( + F: FromState4 +): , S, B>(f: (...a: A) => State) => (...a: A) => Kind4 +export function fromStateK( + F: FromState3 +): , S, B>(f: (...a: A) => State) => (...a: A) => Kind3 +export function fromStateK( + F: FromState3C +): , S, B>(f: (...a: A) => State) => (...a: A) => Kind3 +export function fromStateK( + F: FromState2 +): , S, B>(f: (...a: A) => State) => (...a: A) => Kind2 +export function fromStateK( + F: FromState +): , S, B>(f: (...a: A) => State) => (...a: A) => HKT2 +export function fromStateK( + F: FromState +): , S, B>(f: (...a: A) => State) => (...a: A) => HKT2 { + return (f) => flow(f, F.fromState) +} + +/** + * @category combinators + * @since 2.11.0 + */ +export function chainStateK( + F: FromState4, + M: Chain4 +): (f: (a: A) => State) => (ma: Kind4) => Kind4 +export function chainStateK( + F: FromState3, + M: Chain3 +): (f: (a: A) => State) => (ma: Kind3) => Kind3 +export function chainStateK( + F: FromState2, + M: Chain2 +): (f: (a: A) => State) => (ma: Kind2) => Kind2 +export function chainStateK( + F: FromState, + M: Chain +): (f: (a: A) => State) => (ma: HKT2) => HKT2 +export function chainStateK( + F: FromState2, + M: Chain2 +): (f: (a: A) => State) => (ma: Kind2) => Kind2 { + const fromStateKF = fromStateK(F) + return (f) => (ma) => M.chain(ma, fromStateKF(f)) +} diff --git a/src/FromTask.ts b/src/FromTask.ts index 55f067a69..f702e3090 100644 --- a/src/FromTask.ts +++ b/src/FromTask.ts @@ -7,7 +7,15 @@ import { Chain, Chain1, Chain2, Chain2C, Chain3, Chain3C, Chain4, chainFirst } f import { FromIO, FromIO1, FromIO2, FromIO2C, FromIO3, FromIO3C, FromIO4 } from './FromIO' import { flow } from './function' import { HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT' -import { Task } from './Task' +import { + NaturalTransformation11, + NaturalTransformation12, + NaturalTransformation12C, + NaturalTransformation13, + NaturalTransformation13C, + NaturalTransformation14 +} from './NaturalTransformation' +import { Task, URI } from './Task' // ------------------------------------------------------------------------------------- // model @@ -26,7 +34,7 @@ export interface FromTask extends FromIO { * @since 2.10.0 */ export interface FromTask1 extends FromIO1 { - readonly fromTask: (fa: Task) => Kind + readonly fromTask: NaturalTransformation11 } /** @@ -34,7 +42,7 @@ export interface FromTask1 extends FromIO1 { * @since 2.10.0 */ export interface FromTask2 extends FromIO2 { - readonly fromTask: (fa: Task) => Kind2 + readonly fromTask: NaturalTransformation12 } /** @@ -42,7 +50,7 @@ export interface FromTask2 extends FromIO2 { * @since 2.10.0 */ export interface FromTask2C extends FromIO2C { - readonly fromTask: (fa: Task) => Kind2 + readonly fromTask: NaturalTransformation12C } /** @@ -50,7 +58,7 @@ export interface FromTask2C extends FromIO2C { * @since 2.10.0 */ export interface FromTask3 extends FromIO3 { - readonly fromTask: (fa: Task) => Kind3 + readonly fromTask: NaturalTransformation13 } /** @@ -58,7 +66,7 @@ export interface FromTask3 extends FromIO3 { * @since 2.10.0 */ export interface FromTask3C extends FromIO3C { - readonly fromTask: (fa: Task) => Kind3 + readonly fromTask: NaturalTransformation13C } /** @@ -66,7 +74,7 @@ export interface FromTask3C extends FromIO3C { * @since 2.10.0 */ export interface FromTask4 extends FromIO4 { - readonly fromTask: (fa: Task) => Kind4 + readonly fromTask: NaturalTransformation14 } // ------------------------------------------------------------------------------------- diff --git a/src/FromThese.ts b/src/FromThese.ts new file mode 100644 index 000000000..29dfbbe01 --- /dev/null +++ b/src/FromThese.ts @@ -0,0 +1,107 @@ +/** + * The `FromThese` type class represents those data types which support errors and warnings. + * + * @since 2.11.0 + */ +import { flow } from './function' +import { HKT2, Kind2, Kind3, Kind4, URIS2, URIS3, URIS4 } from './HKT' +import { + NaturalTransformation22, + NaturalTransformation22C, + NaturalTransformation23, + NaturalTransformation23C, + NaturalTransformation24 +} from './NaturalTransformation' +import { These, URI } from './These' + +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromThese { + readonly URI: F + readonly fromThese: (e: These) => HKT2 +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromThese2 { + readonly URI: F + readonly fromThese: NaturalTransformation22 +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromThese2C { + readonly URI: F + readonly _E: E + readonly fromThese: NaturalTransformation22C +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromThese3 { + readonly URI: F + readonly fromThese: NaturalTransformation23 +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromThese3C { + readonly URI: F + readonly _E: E + readonly fromThese: NaturalTransformation23C +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface FromThese4 { + readonly URI: F + readonly fromThese: NaturalTransformation24 +} + +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- + +/** + * @category combinators + * @since 2.11.0 + */ +export function fromTheseK( + F: FromThese4 +): , E, B>(f: (...a: A) => These) => (...a: A) => Kind4 +export function fromTheseK( + F: FromThese3 +): , E, B>(f: (...a: A) => These) => (...a: A) => Kind3 +export function fromTheseK( + F: FromThese3C +): , B>(f: (...a: A) => These) => (...a: A) => Kind3 +export function fromTheseK( + F: FromThese2 +): , E, B>(f: (...a: A) => These) => (...a: A) => Kind2 +export function fromTheseK( + F: FromThese2C +): , B>(f: (...a: A) => These) => (...a: A) => Kind2 +export function fromTheseK( + F: FromThese +): , E, B>(f: (...a: A) => These) => (...a: A) => HKT2 +export function fromTheseK( + F: FromThese +): , E, B>(f: (...a: A) => These) => (...a: A) => HKT2 { + return (f) => flow(f, F.fromThese) +} diff --git a/src/IO.ts b/src/IO.ts index 89ba78f9e..6ca3cebfe 100644 --- a/src/IO.ts +++ b/src/IO.ts @@ -12,17 +12,20 @@ * @since 2.0.0 */ import { Applicative1, getApplicativeMonoid } from './Applicative' -import { apFirst as apFirst_, Apply1, apSecond as apSecond_, apS as apS_, getApplySemigroup } from './Apply' +import { apFirst as apFirst_, Apply1, apS as apS_, apSecond as apSecond_, getApplySemigroup } from './Apply' +import { bind as bind_, Chain1, chainFirst as chainFirst_ } from './Chain' import { ChainRec1 } from './ChainRec' import { FromIO1 } from './FromIO' import { constant, identity } from './function' import { bindTo as bindTo_, flap as flap_, Functor1 } from './Functor' -import { bind as bind_, Chain1, chainFirst as chainFirst_ } from './Chain' +import * as _ from './internal' +import { Monad1 } from './Monad' import { MonadIO1 } from './MonadIO' import { Monoid } from './Monoid' +import { NonEmptyArray } from './NonEmptyArray' import { Pointed1 } from './Pointed' +import { ReadonlyNonEmptyArray } from './ReadonlyNonEmptyArray' import { Semigroup } from './Semigroup' -import { Monad1 } from './Monad' // ------------------------------------------------------------------------------------- // model @@ -96,13 +99,6 @@ export const flatten: (mma: IO>) => IO = /*#__PURE__*/ chain(identity) -/** - * @category constructors - * @since 2.7.0 - * @deprecated - */ -export const fromIO: FromIO1['fromIO'] = identity - // ------------------------------------------------------------------------------------- // instances // ------------------------------------------------------------------------------------- @@ -234,6 +230,13 @@ export const chainFirst = /*#__PURE__*/ chainFirst_(Chain) +/** + * @category constructors + * @since 2.7.0 + * @deprecated + */ +export const fromIO: FromIO1['fromIO'] = identity + /** * @category instances * @since 2.7.0 @@ -277,7 +280,7 @@ export const FromIO: FromIO1 = { */ export const Do: IO<{}> = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 @@ -304,30 +307,60 @@ export const apS = /*#__PURE__*/ apS_(Apply) +// ------------------------------------------------------------------------------------- +// sequence T +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export const ApT: IO = of(_.emptyReadonlyArray) + // ------------------------------------------------------------------------------------- // array utils // ------------------------------------------------------------------------------------- +/** + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. + * + * @since 2.11.0 + */ +export const traverseReadonlyNonEmptyArrayWithIndex = (f: (index: number, a: A) => IO) => ( + as: ReadonlyNonEmptyArray +): IO> => () => { + const out: NonEmptyArray = [f(0, _.head(as))()] + for (let i = 1; i < as.length; i++) { + out.push(f(i, as[i])()) + } + return out +} + /** * Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndex = ( + f: (index: number, a: A) => IO +): ((as: ReadonlyArray) => IO>) => { + const g = traverseReadonlyNonEmptyArrayWithIndex(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + +/** * @since 2.9.0 */ -export const traverseArrayWithIndex = (f: (index: number, a: A) => IO) => ( - as: ReadonlyArray -): IO> => () => as.map((a, i) => f(i, a)()) +export const traverseArrayWithIndex: ( + f: (index: number, a: A) => IO +) => (as: ReadonlyArray) => IO> = traverseReadonlyArrayWithIndex /** - * Equivalent to `ReadonlyArray#traverse(Applicative)`. - * * @since 2.9.0 */ export const traverseArray = (f: (a: A) => IO): ((as: ReadonlyArray) => IO>) => - traverseArrayWithIndex((_, a) => f(a)) + traverseReadonlyArrayWithIndex((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(Applicative)`. - * * @since 2.9.0 */ export const sequenceArray: (arr: ReadonlyArray>) => IO> = @@ -338,6 +371,8 @@ export const sequenceArray: (arr: ReadonlyArray>) => IO(me: IO) => IOEither = /*#__PURE__*/ ET.leftF(I.Functor) +// ------------------------------------------------------------------------------------- +// natural transformations +// ------------------------------------------------------------------------------------- + /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ export const fromEither: FromEither2['fromEither'] = I.of /** - * @category constructors + * @category natural transformations * @since 2.7.0 */ export const fromIO: FromIO2['fromIO'] = rightIO @@ -239,6 +247,30 @@ export const orElseW: ( onLeft: (e: E1) => IOEither ) => (ma: IOEither) => IOEither = orElse as any +/** + * @category combinators + * @since 2.11.0 + */ +export const orElseFirst: (onLeft: (e: E) => IOEither) => (ma: IOEither) => IOEither = + /*#__PURE__*/ + ET.orElseFirst(I.Monad) + +/** + * @category combinators + * @since 2.11.0 + */ +export const orElseFirstW: ( + onLeft: (e: E1) => IOEither +) => (ma: IOEither) => IOEither = orElseFirst as any + +/** + * @category combinators + * @since 2.11.0 + */ +export const orLeft: (onLeft: (e: E1) => IO) => (fa: IOEither) => IOEither = + /*#__PURE__*/ + ET.orLeft(I.Monad) + /** * @category combinators * @since 2.0.0 @@ -252,16 +284,16 @@ export const swap: (ma: IOEither) => IOEither = // ------------------------------------------------------------------------------------- /* istanbul ignore next */ -const _map: Monad2['map'] = (fa, f) => pipe(fa, map(f)) +const _map: Functor2['map'] = (fa, f) => pipe(fa, map(f)) /* istanbul ignore next */ -const _ap: Monad2['ap'] = (fab, fa) => pipe(fab, ap(fa)) -const _apSeq: Applicative2['ap'] = (fab, fa) => +const _ap: Apply2['ap'] = (fab, fa) => pipe(fab, ap(fa)) +const _apSeq: Apply2['ap'] = (fab, fa) => pipe( fab, chain((f) => pipe(fa, map(f))) ) /* istanbul ignore next */ -const _chain: Monad2['chain'] = (ma, f) => pipe(ma, chain(f)) +const _chain: Chain2['chain'] = (ma, f) => pipe(ma, chain(f)) /* istanbul ignore next */ const _bimap: Bifunctor2['bimap'] = (fa, f, g) => pipe(fa, bimap(f, g)) /* istanbul ignore next */ @@ -350,15 +382,23 @@ export const chainW: ( f: (a: A) => IOEither ) => (ma: IOEither) => IOEither = chain as any +/** + * Less strict version of [`flatten`](#flatten). + * + * @category combinators + * @since 2.11.0 + */ +export const flattenW: (mma: IOEither>) => IOEither = + /*#__PURE__*/ + chainW(identity) + /** * Derivable from `Chain`. * * @category combinators * @since 2.0.0 */ -export const flatten: (mma: IOEither>) => IOEither = - /*#__PURE__*/ - chain(identity) +export const flatten: (mma: IOEither>) => IOEither = flattenW /** * Identifies an associative operation on a type constructor. It is similar to `Semigroup`, except that it applies to @@ -698,10 +738,10 @@ export const FromEither: FromEither2 = { } /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ -export const fromOption: (onNone: Lazy) => (ma: Option) => IOEither = +export const fromOption = /*#__PURE__*/ fromOption_(FromEither) @@ -745,6 +785,7 @@ export const chainEitherKW: ( */ export const fromPredicate: { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => IOEither + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => IOEither (predicate: Predicate, onFalse: (a: A) => E): (a: A) => IOEither } = /*#__PURE__*/ @@ -756,6 +797,7 @@ export const fromPredicate: { */ export const filterOrElse: { (refinement: Refinement, onFalse: (a: A) => E): (ma: IOEither) => IOEither + (predicate: Predicate, onFalse: (a: A) => E): (mb: IOEither) => IOEither (predicate: Predicate, onFalse: (a: A) => E): (ma: IOEither) => IOEither } = /*#__PURE__*/ @@ -771,6 +813,9 @@ export const filterOrElseW: { (refinement: Refinement, onFalse: (a: A) => E2): ( ma: IOEither ) => IOEither + (predicate: Predicate, onFalse: (a: A) => E2): ( + mb: IOEither + ) => IOEither (predicate: Predicate, onFalse: (a: A) => E2): (ma: IOEither) => IOEither } = filterOrElse @@ -825,7 +870,7 @@ export const bracket = ( */ export const Do: IOEither = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 @@ -872,32 +917,91 @@ export const apSW: ( fa: IOEither ) => IOEither = apS as any +// ------------------------------------------------------------------------------------- +// sequence T +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export const ApT: IOEither = of(_.emptyReadonlyArray) + // ------------------------------------------------------------------------------------- // array utils // ------------------------------------------------------------------------------------- /** - * Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativePar)`. * - * @since 2.9.0 + * @since 2.11.0 */ -export const traverseArrayWithIndex = ( +export const traverseReadonlyNonEmptyArrayWithIndex: ( f: (index: number, a: A) => IOEither -): ((as: ReadonlyArray) => IOEither>) => - flow(I.traverseArrayWithIndex(f), I.map(E.sequenceArray)) +) => (as: ReadonlyNonEmptyArray) => IOEither> = (f) => + flow(I.traverseReadonlyNonEmptyArrayWithIndex(f), I.map(E.traverseReadonlyNonEmptyArrayWithIndex(SK))) /** - * Equivalent to `ReadonlyArray#traverse(Applicative)`. + * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndex = ( + f: (index: number, a: A) => IOEither +): ((as: ReadonlyArray) => IOEither>) => { + const g = traverseReadonlyNonEmptyArrayWithIndex(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + +/** + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativeSeq)`. + * + * @since 2.11.0 + */ +export const traverseReadonlyNonEmptyArrayWithIndexSeq = (f: (index: number, a: A) => IOEither) => ( + as: ReadonlyNonEmptyArray +): IOEither> => () => { + const e = f(0, _.head(as))() + if (_.isLeft(e)) { + return e + } + const out: NonEmptyArray = [e.right] + for (let i = 1; i < as.length; i++) { + const e = f(i, as[i])() + if (_.isLeft(e)) { + return e + } + out.push(e.right) + } + return _.right(out) +} + +/** + * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. + * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndexSeq = ( + f: (index: number, a: A) => IOEither +): ((as: ReadonlyArray) => IOEither>) => { + const g = traverseReadonlyNonEmptyArrayWithIndexSeq(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + +/** + * @since 2.9.0 + */ +export const traverseArrayWithIndex: ( + f: (index: number, a: A) => IOEither +) => (as: ReadonlyArray) => IOEither> = traverseReadonlyArrayWithIndex + +/** * @since 2.9.0 */ export const traverseArray = ( f: (a: A) => IOEither -): ((as: ReadonlyArray) => IOEither>) => traverseArrayWithIndex((_, a) => f(a)) +): ((as: ReadonlyArray) => IOEither>) => traverseReadonlyArrayWithIndex((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(Applicative)`. - * * @since 2.9.0 */ export const sequenceArray: (arr: ReadonlyArray>) => IOEither> = @@ -905,36 +1009,20 @@ export const sequenceArray: (arr: ReadonlyArray>) => IOEith traverseArray(identity) /** - * Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. - * * @since 2.9.0 */ -export const traverseSeqArrayWithIndex = (f: (index: number, a: A) => IOEither) => ( - as: ReadonlyArray -): IOEither> => () => { - const out = [] - for (let i = 0; i < as.length; i++) { - const b = f(i, as[i])() - if (E.isLeft(b)) { - return b - } - out.push(b.right) - } - return E.right(out) -} +export const traverseSeqArrayWithIndex: ( + f: (index: number, a: A) => IOEither +) => (as: ReadonlyArray) => IOEither> = traverseReadonlyArrayWithIndexSeq /** - * Equivalent to `ReadonlyArray#traverse(ApplicativeSeq)`. - * * @since 2.9.0 */ export const traverseSeqArray = ( f: (a: A) => IOEither -): ((as: ReadonlyArray) => IOEither>) => traverseSeqArrayWithIndex((_, a) => f(a)) +): ((as: ReadonlyArray) => IOEither>) => traverseReadonlyArrayWithIndexSeq((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(ApplicativeSeq)`. - * * @since 2.9.0 */ export const sequenceSeqArray: (arr: ReadonlyArray>) => IOEither> = @@ -945,6 +1033,8 @@ export const sequenceSeqArray: (arr: ReadonlyArray>) => IOE // deprecated // ------------------------------------------------------------------------------------- +// tslint:disable: deprecation + /** * Use [`ApplicativePar`](#applicativepar) instead * diff --git a/src/Identity.ts b/src/Identity.ts index 962538184..afa497f25 100644 --- a/src/Identity.ts +++ b/src/Identity.ts @@ -3,7 +3,8 @@ */ import { Alt1 } from './Alt' import { Applicative as ApplicativeHKT, Applicative1 } from './Applicative' -import { apFirst as apFirst_, Apply1, apSecond as apSecond_, apS as apS_ } from './Apply' +import { apFirst as apFirst_, Apply1, apS as apS_, apSecond as apSecond_ } from './Apply' +import { bind as bind_, Chain1, chainFirst as chainFirst_ } from './Chain' import { ChainRec1, tailRec } from './ChainRec' import { Comonad1 } from './Comonad' import { Eq } from './Eq' @@ -12,12 +13,12 @@ import { Foldable1 } from './Foldable' import { identity as id, pipe } from './function' import { bindTo as bindTo_, flap as flap_, Functor1 } from './Functor' import { HKT } from './HKT' -import { bind as bind_, Chain1, chainFirst as chainFirst_ } from './Chain' +import * as _ from './internal' +import { Monad1 } from './Monad' import { Monoid } from './Monoid' import { Pointed1 } from './Pointed' import { Show } from './Show' import { PipeableTraverse1, Traversable1 } from './Traversable' -import { Monad1 } from './Monad' // ------------------------------------------------------------------------------------- // model @@ -383,7 +384,7 @@ export const ChainRec: ChainRec1 = { */ export const Do: Identity<{}> = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 diff --git a/src/Json.ts b/src/Json.ts index fd2acbbb8..4a188af53 100644 --- a/src/Json.ts +++ b/src/Json.ts @@ -1,7 +1,7 @@ /** * @since 2.10.0 */ -import { Either, parseJSON, stringifyJSON } from './Either' +import { Either, tryCatch } from './Either' import { identity } from './function' /** @@ -34,8 +34,7 @@ export interface JsonArray extends ReadonlyArray {} * * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const parse = (s: string): Either => parseJSON(s, identity) +export const parse = (s: string): Either => tryCatch(() => JSON.parse(s), identity) /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. @@ -58,5 +57,11 @@ export const parse = (s: string): Either => parseJSON(s, identity * * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const stringify = (a: A): Either => stringifyJSON(a, identity) +export const stringify = (a: A): Either => + tryCatch(() => { + const s = JSON.stringify(a) + if (typeof s !== 'string') { + throw new Error('Converting unsupported structure to JSON') + } + return s + }, identity) diff --git a/src/Magma.ts b/src/Magma.ts index c00cae5ae..83e3f7abd 100644 --- a/src/Magma.ts +++ b/src/Magma.ts @@ -6,6 +6,9 @@ * @since 2.0.0 */ +import { Endomorphism } from './Endomorphism' +import { Predicate } from './Predicate' + // ------------------------------------------------------------------------------------- // model // ------------------------------------------------------------------------------------- @@ -17,3 +20,71 @@ export interface Magma { readonly concat: (x: A, y: A) => A } + +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- + +/** + * The dual of a `Magma`, obtained by swapping the arguments of `concat`. + * + * @example + * import { reverse, concatAll } from 'fp-ts/Magma' + * import * as N from 'fp-ts/number' + * + * const subAll = concatAll(reverse(N.MagmaSub))(0) + * + * assert.deepStrictEqual(subAll([1, 2, 3]), 2) + * + * @category combinators + * @since 2.11.0 + */ +export const reverse = (M: Magma): Magma => ({ + concat: (first, second) => M.concat(second, first) +}) + +/** + * @category combinators + * @since 2.11.0 + */ +export const filterFirst = (predicate: Predicate) => (M: Magma): Magma => ({ + concat: (first, second) => (predicate(first) ? M.concat(first, second) : second) +}) + +/** + * @category combinators + * @since 2.11.0 + */ +export const filterSecond = (predicate: Predicate) => (M: Magma): Magma => ({ + concat: (first, second) => (predicate(second) ? M.concat(first, second) : first) +}) + +/** + * @category combinators + * @since 2.11.0 + */ +export const endo = (f: Endomorphism) => (M: Magma): Magma => ({ + concat: (first, second) => M.concat(f(first), f(second)) +}) + +// ------------------------------------------------------------------------------------- +// utils +// ------------------------------------------------------------------------------------- + +/** + * Given a sequence of `as`, concat them and return the total. + * + * If `as` is empty, return the provided `startWith` value. + * + * @example + * import { concatAll } from 'fp-ts/Magma' + * import * as N from 'fp-ts/number' + * + * const subAll = concatAll(N.MagmaSub)(0) + * + * assert.deepStrictEqual(subAll([1, 2, 3]), -6) + * + * @since 2.11.0 + */ +export const concatAll = (M: Magma) => (startWith: A) => (as: ReadonlyArray): A => + as.reduce((a, acc) => M.concat(a, acc), startWith) diff --git a/src/Map.ts b/src/Map.ts index 2cd6430b7..776e51688 100644 --- a/src/Map.ts +++ b/src/Map.ts @@ -3,26 +3,29 @@ */ import { Applicative } from './Applicative' import { Compactable2 } from './Compactable' -import { Either, isLeft } from './Either' +import { Either } from './Either' import { Eq } from './Eq' import { Filterable2 } from './Filterable' import { FilterableWithIndex2C } from './FilterableWithIndex' -import { Foldable, Foldable1, Foldable2, Foldable3 } from './Foldable' +import { Foldable, Foldable1, Foldable2, Foldable2C, Foldable3 } from './Foldable' import { FoldableWithIndex2C } from './FoldableWithIndex' -import { pipe, Predicate, Refinement } from './function' +import { pipe } from './function' import { flap as flap_, Functor2 } from './Functor' import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT' +import * as _ from './internal' import { Magma } from './Magma' import { Monoid } from './Monoid' import * as O from './Option' import { Ord } from './Ord' +import { Predicate } from './Predicate' import * as RM from './ReadonlyMap' +import { Refinement } from './Refinement' import { Semigroup } from './Semigroup' import { separated, Separated } from './Separated' import { Show } from './Show' import { TraversableWithIndex2C } from './TraversableWithIndex' import { Unfoldable, Unfoldable1 } from './Unfoldable' -import { Witherable2C } from './Witherable' +import { wiltDefault, Witherable2C, witherDefault } from './Witherable' import Option = O.Option @@ -37,14 +40,14 @@ export const getShow: (SK: Show, SA: Show) => Show> = RM.g * * @since 2.0.0 */ -export const size: (d: Map) => number = RM.size +export const size: (m: Map) => number = RM.size /** * Test whether or not a map is empty * * @since 2.0.0 */ -export const isEmpty: (d: Map) => boolean = RM.isEmpty +export const isEmpty: (m: Map) => boolean = RM.isEmpty // TODO: remove non-curried overloading in v3 /** @@ -122,7 +125,7 @@ export function toUnfoldable(ord: Ord, U: Unfoldable): (d: Map { const kas = toArrayO(d) const len = kas.length - return U.unfold(0, (b) => (b < len ? O.some([kas[b], b + 1]) : O.none)) + return U.unfold(0, (b) => (b < len ? _.some([kas[b], b + 1]) : _.none)) } } @@ -138,7 +141,7 @@ export const upsertAt = (E: Eq): ((k: K, a: A) => (m: Map) => Map const lookupWithKeyEk = lookupWithKeyE(k) return (m) => { const found = lookupWithKeyEk(m) - if (O.isNone(found)) { + if (_.isNone(found)) { const out = new Map(m) out.set(k, a) return out @@ -162,7 +165,7 @@ export const deleteAt = (E: Eq): ((k: K) => (m: Map) => Map const lookupWithKeyE = lookupWithKey(E) return (k) => (m) => { const found = lookupWithKeyE(k, m) - if (O.isSome(found)) { + if (_.isSome(found)) { const r = new Map(m) r.delete(found.value[0]) return r @@ -186,12 +189,12 @@ export const modifyAt = (E: Eq): ((k: K, f: (a: A) => A) => (m: Map (m) => { const found = lookupWithKeyE(k, m) - if (O.isNone(found)) { - return O.none + if (_.isNone(found)) { + return _.none } const r = new Map(m) r.set(found.value[0], f(found.value[1])) - return O.some(r) + return _.some(r) } } @@ -245,10 +248,10 @@ export function lookupWithKey( while (!(e = entries.next()).done) { const [ka, a] = e.value if (E.equals(ka, k)) { - return O.some([ka, a]) + return _.some([ka, a]) } } - return O.none + return _.none } } @@ -308,7 +311,7 @@ export function getMonoid(SK: Eq, SA: Semigroup): Monoid> while (!(e = entries.next()).done) { const [k, a] = e.value const mxOptA = lookupWithKeyS(k, mx) - if (O.isSome(mxOptA)) { + if (_.isSome(mxOptA)) { r.set(mxOptA.value[0], SA.concat(mxOptA.value[1], a)) } else { r.set(k, a) @@ -355,7 +358,7 @@ export function fromFoldable(E: Eq, M: Magma, F: Foldable): (f const lookupWithKeyE = lookupWithKey(E) return F.reduce<[K, A], Map>(fka, new Map(), (b, [k, a]) => { const bOpt = lookupWithKeyE(k, b) - if (O.isSome(bOpt)) { + if (_.isSome(bOpt)) { b.set(bOpt.value[0], M.concat(bOpt.value[1], a)) } else { b.set(k, a) @@ -392,7 +395,7 @@ export const partitionMapWithIndex = (f: (k: K, a: A) => Either(f: (k: K, a: A) => Either(p: (k: K, a: A) => boolean) => ( - fa: Map -): Separated, Map> => { - const left = new Map() - const right = new Map() - const entries = fa.entries() - let e: Next<[K, A]> - // tslint:disable-next-line: strict-boolean-expressions - while (!(e = entries.next()).done) { - const [k, a] = e.value - if (p(k, a)) { - right.set(k, a) - } else { - left.set(k, a) +export function partitionWithIndex( + predicateWithIndex: (k: K, a: A) => a is B +): (fa: Map) => Separated, Map> +export function partitionWithIndex( + predicateWithIndex: (k: K, a: A) => boolean +): (fb: Map) => Separated, Map> +export function partitionWithIndex( + predicateWithIndex: (k: K, a: A) => boolean +): (fa: Map) => Separated, Map> +export function partitionWithIndex( + predicateWithIndex: (k: K, a: A) => boolean +): (fa: Map) => Separated, Map> { + return (fa: Map) => { + const left = new Map() + const right = new Map() + const entries = fa.entries() + let e: Next<[K, A]> + // tslint:disable-next-line: strict-boolean-expressions + while (!(e = entries.next()).done) { + const [k, a] = e.value + if (predicateWithIndex(k, a)) { + right.set(k, a) + } else { + left.set(k, a) + } } + return separated(left, right) } - return separated(left, right) } /** @@ -436,7 +450,7 @@ export const filterMapWithIndex = (f: (k: K, a: A) => Option) => (fa while (!(e = entries.next()).done) { const [k, a] = e.value const o = f(k, a) - if (O.isSome(o)) { + if (_.isSome(o)) { m.set(k, o.value) } } @@ -447,18 +461,23 @@ export const filterMapWithIndex = (f: (k: K, a: A) => Option) => (fa * @category combinators * @since 2.10.0 */ -export const filterWithIndex = (p: (k: K, a: A) => boolean) => (m: Map): Map => { - const out = new Map() - const entries = m.entries() - let e: Next<[K, A]> - // tslint:disable-next-line: strict-boolean-expressions - while (!(e = entries.next()).done) { - const [k, a] = e.value - if (p(k, a)) { - out.set(k, a) +export function filterWithIndex(p: (k: K, a: A) => a is B): (m: Map) => Map +export function filterWithIndex(p: (k: K, a: A) => boolean): (m: Map) => Map +export function filterWithIndex(p: (k: K, a: A) => boolean): (m: Map) => Map +export function filterWithIndex(p: (k: K, a: A) => boolean): (m: Map) => Map { + return (m: Map) => { + const out = new Map() + const entries = m.entries() + let e: Next<[K, A]> + // tslint:disable-next-line: strict-boolean-expressions + while (!(e = entries.next()).done) { + const [k, a] = e.value + if (p(k, a)) { + out.set(k, a) + } } + return out } - return out } // ------------------------------------------------------------------------------------- @@ -493,7 +512,7 @@ export const compact = (fa: Map>): Map => { // tslint:disable-next-line: strict-boolean-expressions while (!(e = entries.next()).done) { const [k, oa] = e.value - if (O.isSome(oa)) { + if (_.isSome(oa)) { m.set(k, oa.value) } } @@ -506,6 +525,7 @@ export const compact = (fa: Map>): Map => { */ export const filter: { (refinement: Refinement): (fa: Map) => Map + (predicate: Predicate): (fb: Map) => Map (predicate: Predicate): (fa: Map) => Map } = (predicate: Predicate) => (fa: Map) => _filter(fa, predicate) @@ -538,6 +558,7 @@ export const mapWithIndex: (f: (k: K, a: A) => B) => (fa: Map) => */ export const partition: { (refinement: Refinement): (fa: Map) => Separated, Map> + (predicate: Predicate): (fb: Map) => Separated, Map> (predicate: Predicate): (fa: Map) => Separated, Map> } = (predicate: Predicate) => (fa: Map) => _partition(fa, predicate) @@ -561,7 +582,7 @@ export const separate = (fa: Map>): Separated // tslint:disable-next-line: strict-boolean-expressions while (!(e = entries.next()).done) { const [k, ei] = e.value - if (isLeft(ei)) { + if (_.isLeft(ei)) { left.set(k, ei.left) } else { right.set(k, ei.right) @@ -592,6 +613,48 @@ declare module './HKT' { } } +/** + * @category instances + * @since 2.11.0 + */ +export const getUnionSemigroup = (E: Eq, S: Semigroup): Semigroup> => { + const unionES = union(E, S) + return { + concat: (first, second) => unionES(second)(first) + } +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getUnionMonoid = (E: Eq, S: Semigroup): Monoid> => ({ + concat: getUnionSemigroup(E, S).concat, + empty: new Map() +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const getIntersectionSemigroup = (E: Eq, S: Semigroup): Semigroup> => { + const intersectionES = intersection(E, S) + return { + concat: (first, second) => intersectionES(second)(first) + } +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getDifferenceMagma = (E: Eq) => (): Magma> => { + const differenceE = difference(E) + return { + concat: (first, second) => differenceE(second)(first) + } +} + /** * @category instances * @since 2.0.0 @@ -641,71 +704,63 @@ export function getWitherable(O: Ord): Witherable2C & TraversableW foldMapWithIndex: TWI.foldMapWithIndex, reduceRightWithIndex: TWI.reduceRightWithIndex, traverseWithIndex: TWI.traverseWithIndex, - wilt: ( - F: Applicative - ): ((wa: Map, f: (a: A) => HKT>) => HKT, Map>>) => { - const traverseF = TWI.traverse(F) - return (wa, f) => F.map(traverseF(wa, f), separate) - }, - wither: (F: Applicative): ((wa: Map, f: (a: A) => HKT>) => HKT>) => { - const traverseF = TWI.traverse(F) - return (wa, f) => F.map(traverseF(wa, f), compact) - } + wilt: wiltDefault(TWI, Compactable), + wither: witherDefault(TWI, Compactable) } } /** - * @category instances - * @since 2.10.0 + * @since 2.11.0 */ -export const getFoldableWithIndex = (O: Ord): FoldableWithIndex2C => { - const keysO = keys(O) +export const reduce: (O: Ord) => (b: B, f: (b: B, a: A) => B) => (m: Map) => B = RM.reduce - const reduceWithIndex = (fa: Map, b: B, f: (k: K, b: B, a: A) => B): B => { - let out: B = b - const ks = keysO(fa) - const len = ks.length - for (let i = 0; i < len; i++) { - const k = ks[i] - out = f(k, out, fa.get(k)!) - } - return out - } +/** + * @since 2.11.0 + */ +export const foldMap: (O: Ord) => (M: Monoid) => (f: (a: A) => M) => (m: Map) => M = RM.foldMap - const foldMapWithIndex = (M: Monoid) => (fa: Map, f: (k: K, a: A) => M): M => { - let out: M = M.empty - const ks = keysO(fa) - const len = ks.length - for (let i = 0; i < len; i++) { - const k = ks[i] - out = M.concat(out, f(k, fa.get(k)!)) - } - return out - } +/** + * @since 2.11.0 + */ +export const reduceRight: (O: Ord) => (b: B, f: (a: A, b: B) => B) => (m: Map) => B = RM.reduceRight - const reduceRightWithIndex = (fa: Map, b: B, f: (k: K, a: A, b: B) => B): B => { - let out: B = b - const ks = keysO(fa) - const len = ks.length - for (let i = len - 1; i >= 0; i--) { - const k = ks[i] - out = f(k, fa.get(k)!, out) - } - return out +/** + * @category instances + * @since 2.11.0 + */ +export const getFoldable = (O: Ord): Foldable2C => { + return { + ...RM.getFoldable(O), + URI } +} + +/** + * @since 2.11.0 + */ +export const reduceWithIndex: (O: Ord) => (b: B, f: (k: K, b: B, a: A) => B) => (m: Map) => B = + RM.reduceWithIndex + +/** + * @since 2.11.0 + */ +export const foldMapWithIndex: (O: Ord) => (M: Monoid) => (f: (k: K, a: A) => M) => (m: Map) => M = + RM.foldMapWithIndex +/** + * @since 2.11.0 + */ +export const reduceRightWithIndex: (O: Ord) => (b: B, f: (k: K, a: A, b: B) => B) => (m: Map) => B = + RM.reduceRightWithIndex + +/** + * @category instances + * @since 2.10.0 + */ +export const getFoldableWithIndex = (O: Ord): FoldableWithIndex2C => { return { - URI, - _E: undefined as any, - reduce: (fa, b, f) => reduceWithIndex(fa, b, (_, b, a) => f(b, a)), - foldMap: (M) => { - const foldMapWithIndexM = foldMapWithIndex(M) - return (fa, f) => foldMapWithIndexM(fa, (_, a) => f(a)) - }, - reduceRight: (fa, b, f) => reduceRightWithIndex(fa, b, (_, a, b) => f(a, b)), - reduceWithIndex, - foldMapWithIndex, - reduceRightWithIndex + ...RM.getFoldableWithIndex(O), + URI } } @@ -804,6 +859,57 @@ export const Filterable: Filterable2 = { partitionMap: _partitionMap } +// ------------------------------------------------------------------------------------- +// utils +// ------------------------------------------------------------------------------------- + +const copy = (m: Map): Map => new Map(m) + +/** + * @since 2.11.0 + */ +export const union = (E: Eq, M: Magma): ((second: Map) => (first: Map) => Map) => { + const unionEM = RM.union(E, M) + return (second) => (first) => { + if (isEmpty(first)) { + return copy(second) + } + if (isEmpty(second)) { + return copy(first) + } + return unionEM(second)(first) as any + } +} + +/** + * @since 2.11.0 + */ +export const intersection = (E: Eq, M: Magma): ((second: Map) => (first: Map) => Map) => { + const intersectionEM = RM.intersection(E, M) + return (second) => (first) => { + if (isEmpty(first) || isEmpty(second)) { + return new Map() + } + return intersectionEM(second)(first) as any + } +} + +/** + * @since 2.11.0 + */ +export const difference = (E: Eq): ((_second: Map) => (first: Map) => Map) => { + const differenceE = RM.difference(E) + return (second: Map) => (first: Map) => { + if (isEmpty(first)) { + return copy(second) + } + if (isEmpty(second)) { + return copy(first) + } + return differenceE(second)(first) as any + } +} + // ------------------------------------------------------------------------------------- // deprecated // ------------------------------------------------------------------------------------- diff --git a/src/Monoid.ts b/src/Monoid.ts index 66acbcec3..571988ab9 100644 --- a/src/Monoid.ts +++ b/src/Monoid.ts @@ -33,7 +33,8 @@ * @since 2.0.0 */ import { Bounded } from './Bounded' -import { Endomorphism, getEndomorphismMonoid as getEM, getMonoid } from './function' +import { getMonoid as getFM } from './function' +import { Endomorphism, getMonoid as getEM } from './Endomorphism' import * as _ from './internal' import { ReadonlyRecord } from './ReadonlyRecord' import * as Se from './Semigroup' @@ -177,15 +178,6 @@ export const tuple = >( empty: monoids.map((m) => m.empty) } as any) -/** - * @category instances - * @since 2.0.0 - */ -export const monoidVoid: Monoid = { - concat: Se.semigroupVoid.concat, - empty: undefined -} - // ------------------------------------------------------------------------------------- // utils // ------------------------------------------------------------------------------------- @@ -210,6 +202,20 @@ export const concatAll = (M: Monoid): ((as: ReadonlyArray) => A) => Se. // deprecated // ------------------------------------------------------------------------------------- +// tslint:disable: deprecation + +/** + * Use [`Monoid`](./void.ts.html#monoid) instead. + * + * @category instances + * @since 2.0.0 + * @deprecated + */ +export const monoidVoid: Monoid = { + concat: Se.semigroupVoid.concat, + empty: undefined +} + /** * Use [`tuple`](#tuple) instead. * @@ -275,7 +281,6 @@ export const fold = concatAll * @deprecated */ export const monoidAll: Monoid = { - // tslint:disable-next-line: deprecation concat: Se.semigroupAll.concat, empty: true } @@ -288,7 +293,6 @@ export const monoidAll: Monoid = { * @deprecated */ export const monoidAny: Monoid = { - // tslint:disable-next-line: deprecation concat: Se.semigroupAny.concat, empty: false } @@ -300,7 +304,7 @@ export const monoidAny: Monoid = { * @since 2.0.0 * @deprecated */ -export const getFunctionMonoid: (M: Monoid) => () => Monoid<(a: A) => M> = getMonoid +export const getFunctionMonoid: (M: Monoid) => () => Monoid<(a: A) => M> = getFM /** * Use [`getEndomorphismMonoid`](./function.ts.html#getendomorphismmonoid) instead. @@ -321,7 +325,6 @@ export const getEndomorphismMonoid = (): Monoid> => r * @deprecated */ export const monoidString: Monoid = { - // tslint:disable-next-line: deprecation concat: Se.semigroupString.concat, empty: '' } @@ -334,7 +337,6 @@ export const monoidString: Monoid = { * @deprecated */ export const monoidSum: Monoid = { - // tslint:disable-next-line: deprecation concat: Se.semigroupSum.concat, empty: 0 } @@ -347,7 +349,6 @@ export const monoidSum: Monoid = { * @deprecated */ export const monoidProduct: Monoid = { - // tslint:disable-next-line: deprecation concat: Se.semigroupProduct.concat, empty: 1 } diff --git a/src/NaturalTransformation.ts b/src/NaturalTransformation.ts new file mode 100644 index 000000000..7ec0370ef --- /dev/null +++ b/src/NaturalTransformation.ts @@ -0,0 +1,152 @@ +/** + * A type for natural transformations. + * + * A natural transformation is a mapping between type constructors of kind `* -> *` where the mapping + * operation has no ability to manipulate the inner values. + * + * The definition of a natural transformation in category theory states that `F` and `G` should be functors, + * but the `Functor` constraint is not enforced here; that the types are of kind `* -> *` is enough for our purposes. + * + * @since 2.11.0 + */ +import { HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT' + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation { + (fa: HKT): HKT +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation11 { + (fa: Kind): Kind +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation12 { + (fa: Kind): Kind2 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation12C { + (fa: Kind): Kind2 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation13 { + (fa: Kind): Kind3 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation13C { + (fa: Kind): Kind3 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation14 { + (fa: Kind): Kind4 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation14C { + (fa: Kind): Kind4 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation21 { + (fa: Kind2): Kind +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation22 { + (fa: Kind2): Kind2 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation22C { + (fa: Kind2): Kind2 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation23 { + (fa: Kind2): Kind3 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation23C { + (fa: Kind2): Kind3 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation24 { + (fa: Kind2): Kind4 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation23R { + (fa: Kind2): Kind3 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation23RC { + (fa: Kind2): Kind3 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation24R { + (fa: Kind2): Kind4 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation24S { + (fa: Kind2): Kind4 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation33 { + (fa: Kind3): Kind3 +} + +/** + * @since 2.11.0 + */ +export interface NaturalTransformation34 { + (fa: Kind3): Kind4 +} diff --git a/src/NonEmptyArray.ts b/src/NonEmptyArray.ts index 7c9d3894a..1e29ec95d 100644 --- a/src/NonEmptyArray.ts +++ b/src/NonEmptyArray.ts @@ -17,27 +17,29 @@ import { Applicative as ApplicativeHKT, Applicative1 } from './Applicative' import { apFirst as apFirst_, Apply1, apS as apS_, apSecond as apSecond_ } from './Apply' import { bind as bind_, Chain1, chainFirst as chainFirst_ } from './Chain' import { Comonad1 } from './Comonad' +import { Endomorphism } from './Endomorphism' import { Eq } from './Eq' import { Extend1 } from './Extend' import { Foldable1 } from './Foldable' import { FoldableWithIndex1 } from './FoldableWithIndex' -import { identity, Lazy, pipe, Predicate, Refinement } from './function' +import { identity, Lazy, pipe } from './function' import { bindTo as bindTo_, flap as flap_, Functor1 } from './Functor' import { FunctorWithIndex1 } from './FunctorWithIndex' import { HKT } from './HKT' import * as _ from './internal' import { Monad1 } from './Monad' -import * as O from './Option' +import { Option } from './Option' import { getMonoid, Ord } from './Ord' import { Pointed1 } from './Pointed' +import { Predicate } from './Predicate' import * as RNEA from './ReadonlyNonEmptyArray' +import { Refinement } from './Refinement' import * as Se from './Semigroup' import { Show } from './Show' import { PipeableTraverse1, Traversable1 } from './Traversable' import { PipeableTraverseWithIndex1, TraversableWithIndex1 } from './TraversableWithIndex' import Semigroup = Se.Semigroup -import Option = O.Option import ReadonlyNonEmptyArray = RNEA.ReadonlyNonEmptyArray // ------------------------------------------------------------------------------------- @@ -70,12 +72,22 @@ export const isOutOfBound = (i: number, as: Array): boolean => i < 0 || i /** * @internal */ -export const prepend = (head: A) => (tail: Array): NonEmptyArray => [head, ...tail] +export const prependW = (head: B) => (tail: Array): NonEmptyArray => [head, ...tail] /** * @internal */ -export const append = (end: A) => (init: Array): NonEmptyArray => concat(init, [end]) +export const prepend: (head: A) => (tail: Array) => NonEmptyArray = prependW + +/** + * @internal + */ +export const appendW = (end: B) => (init: Array): NonEmptyArray => [...init, end] as any + +/** + * @internal + */ +export const append: (end: A) => (init: Array) => NonEmptyArray = appendW /** * @internal @@ -99,7 +111,16 @@ export const unsafeUpdateAt = (i: number, a: A, as: NonEmptyArray): NonEmp } /** - * @internal + * Remove duplicates from a `NonEmptyArray`, keeping the first occurrence of an element. + * + * @example + * import { uniq } from 'fp-ts/NonEmptyArray' + * import * as N from 'fp-ts/number' + * + * assert.deepStrictEqual(uniq(N.Eq)([1, 2, 1]), [1, 2]) + * + * @category combinators + * @since 2.11.0 */ export const uniq = (E: Eq) => (as: NonEmptyArray): NonEmptyArray => { if (as.length === 1) { @@ -116,7 +137,43 @@ export const uniq = (E: Eq) => (as: NonEmptyArray): NonEmptyArray => } /** - * @internal + * Sort the elements of a `NonEmptyArray` in increasing order, where elements are compared using first `ords[0]`, then `ords[1]`, + * etc... + * + * @example + * import * as NEA from 'fp-ts/NonEmptyArray' + * import { contramap } from 'fp-ts/Ord' + * import * as S from 'fp-ts/string' + * import * as N from 'fp-ts/number' + * import { pipe } from 'fp-ts/function' + * + * interface Person { + * name: string + * age: number + * } + * + * const byName = pipe(S.Ord, contramap((p: Person) => p.name)) + * + * const byAge = pipe(N.Ord, contramap((p: Person) => p.age)) + * + * const sortByNameByAge = NEA.sortBy([byName, byAge]) + * + * const persons: NEA.NonEmptyArray = [ + * { name: 'a', age: 1 }, + * { name: 'b', age: 3 }, + * { name: 'c', age: 2 }, + * { name: 'b', age: 2 } + * ] + * + * assert.deepStrictEqual(sortByNameByAge(persons), [ + * { name: 'a', age: 1 }, + * { name: 'b', age: 2 }, + * { name: 'b', age: 3 }, + * { name: 'c', age: 2 } + * ]) + * + * @category combinators + * @since 2.11.0 */ export const sortBy = (ords: Array>): ((as: NonEmptyArray) => NonEmptyArray) => { if (isNonEmpty(ords)) { @@ -127,15 +184,25 @@ export const sortBy = (ords: Array>): ((as: NonEmptyArray } /** - * @internal + * @category combinators + * @since 2.11.0 */ -export const union = (E: Eq): Semigroup>['concat'] => { +export const union = (E: Eq): ((second: NonEmptyArray) => (first: NonEmptyArray) => NonEmptyArray) => { const uniqE = uniq(E) - return (first, second) => uniqE(concat(first, second)) + return (second) => (first) => uniqE(pipe(first, concat(second))) } /** - * @internal + * Rotate a `NonEmptyArray` by `n` steps. + * + * @example + * import { rotate } from 'fp-ts/NonEmptyArray' + * + * assert.deepStrictEqual(rotate(2)([1, 2, 3, 4, 5]), [4, 5, 1, 2, 3]) + * assert.deepStrictEqual(rotate(-2)([1, 2, 3, 4, 5]), [3, 4, 5, 1, 2]) + * + * @category combinators + * @since 2.11.0 */ export const rotate = (n: number) => (as: NonEmptyArray): NonEmptyArray => { const len = as.length @@ -145,16 +212,47 @@ export const rotate = (n: number) => (as: NonEmptyArray): NonEmptyArray } if (m < 0) { const [f, s] = splitAt(-m)(as) - return concat(s, f) + return pipe(s, concat(f)) } else { return rotate(m - len)(as) } } +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- + /** - * @internal + * @category constructors + * @since 2.10.0 + */ +export const fromReadonlyNonEmptyArray: (as: ReadonlyNonEmptyArray) => NonEmptyArray = + _.fromReadonlyNonEmptyArray + +/** + * Builds a `NonEmptyArray` from an `Array` returning `none` if `as` is an empty array + * + * @category constructors + * @since 2.0.0 + */ +export const fromArray = (as: Array): Option> => (isNonEmpty(as) ? _.some(as) : _.none) + +/** + * Return a `NonEmptyArray` of length `n` with element `i` initialized with `f(i)`. + * + * **Note**. `n` is normalized to a natural number. + * + * @example + * import { makeBy } from 'fp-ts/NonEmptyArray' + * import { pipe } from 'fp-ts/function' + * + * const double = (n: number): number => n * 2 + * assert.deepStrictEqual(pipe(5, makeBy(double)), [0, 2, 4, 6, 8]) + * + * @category constructors + * @since 2.11.0 */ -export const makeBy = (n: number, f: (i: number) => A): NonEmptyArray => { +export const makeBy = (f: (i: number) => A) => (n: number): NonEmptyArray => { const j = Math.max(0, Math.floor(n)) const out: NonEmptyArray = [f(0)] for (let i = 1; i < j; i++) { @@ -163,24 +261,35 @@ export const makeBy = (n: number, f: (i: number) => A): NonEmptyArray => { return out } -// ------------------------------------------------------------------------------------- -// constructors -// ------------------------------------------------------------------------------------- - /** + * Create a `NonEmptyArray` containing a value repeated the specified number of times. + * + * **Note**. `n` is normalized to a natural number. + * + * @example + * import { replicate } from 'fp-ts/NonEmptyArray' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual(pipe(3, replicate('a')), ['a', 'a', 'a']) + * * @category constructors - * @since 2.10.0 + * @since 2.11.0 */ -export const fromReadonlyNonEmptyArray: (as: ReadonlyNonEmptyArray) => NonEmptyArray = - _.fromReadonlyNonEmptyArray +export const replicate = (a: A): ((n: number) => ReadonlyNonEmptyArray) => makeBy(() => a) /** - * Builds a `NonEmptyArray` from an `Array` returning `none` if `as` is an empty array + * Create a `NonEmptyArray` containing a range of integers, including both endpoints. + * + * @example + * import { range } from 'fp-ts/NonEmptyArray' + * + * assert.deepStrictEqual(range(1, 5), [1, 2, 3, 4, 5]) * * @category constructors - * @since 2.0.0 + * @since 2.11.0 */ -export const fromArray = (as: Array): Option> => (isNonEmpty(as) ? O.some(as) : O.none) +export const range = (start: number, end: number): NonEmptyArray => + start <= end ? makeBy((i) => start + i)(end - start + 1) : [start] // ------------------------------------------------------------------------------------- // destructors @@ -216,15 +325,28 @@ export const unappend = (as: NonEmptyArray): [Array, A] => [init(as), l // combinators // ------------------------------------------------------------------------------------- -// TODO: curry in v3 +/** + * @category combinators + * @since 2.11.0 + */ +export function concatW(second: NonEmptyArray): (first: Array) => NonEmptyArray +export function concatW(second: Array): (first: NonEmptyArray) => NonEmptyArray +export function concatW(second: Array): (first: NonEmptyArray) => Array { + return (first: NonEmptyArray) => first.concat(second) +} + /** * @category combinators * @since 2.2.0 */ +export function concat(second: NonEmptyArray): (first: Array) => NonEmptyArray +export function concat(second: Array): (first: NonEmptyArray) => NonEmptyArray +/** @deprecated */ export function concat(first: Array, second: NonEmptyArray): NonEmptyArray +/** @deprecated */ export function concat(first: NonEmptyArray, second: Array): NonEmptyArray -export function concat(first: Array, second: Array): Array { - return first.concat(second) +export function concat(x: Array, y?: Array): Array | ((y: NonEmptyArray) => Array) { + return y ? x.concat(y) : (y) => y.concat(x) } /** @@ -279,30 +401,6 @@ export function group(E: Eq): (as: Array) => Array> { } } -/** - * Sort and then group the elements of an array into non empty arrays. - * - * @example - * import { groupSort } from 'fp-ts/NonEmptyArray' - * import * as N from 'fp-ts/number' - * - * assert.deepStrictEqual(groupSort(N.Ord)([1, 2, 1, 1]), [[1, 1, 1], [2]]) - * - * @category combinators - * @since 2.0.0 - */ -export function groupSort( - O: Ord -): { - (as: NonEmptyArray): NonEmptyArray> - (as: Array): Array> -} -export function groupSort(O: Ord): (as: Array) => Array> { - const sortO = sort(O) - const groupO = group(O) - return (as) => (isNonEmpty(as) ? groupO(sortO(as)) : []) -} - /** * Splits an array into sub-non-empty-arrays stored in an object, based on the result of calling a `string`-returning * function on each element, and grouping the results according to values returned @@ -343,7 +441,7 @@ export const sort = (O: Ord) => (as: NonEmptyArray): NonEm * @since 2.0.0 */ export const insertAt = (i: number, a: A) => (as: Array): Option> => - i < 0 || i > as.length ? O.none : O.some(unsafeInsertAt(i, a, as)) + i < 0 || i > as.length ? _.none : _.some(unsafeInsertAt(i, a, as)) /** * @category combinators @@ -357,7 +455,7 @@ export const updateAt = (i: number, a: A): ((as: NonEmptyArray) => Option< * @since 2.0.0 */ export const modifyAt = (i: number, f: (a: A) => A) => (as: NonEmptyArray): Option> => - isOutOfBound(i, as) ? O.none : O.some(unsafeUpdateAt(i, f(as[i]), as)) + isOutOfBound(i, as) ? _.none : _.some(unsafeUpdateAt(i, f(as[i]), as)) /** * @category combinators @@ -575,7 +673,7 @@ const _traverseWithIndex: TraversableWithIndex1['traverseWithIndex' * @since 2.9.0 */ export const altW = (that: Lazy>) => (as: NonEmptyArray): NonEmptyArray => - concat(as as NonEmptyArray, that()) + pipe(as, concatW(that())) /** * Identifies an associative operation on a type constructor. It is similar to `Semigroup`, except that it applies to @@ -775,6 +873,17 @@ export const getSemigroup = (): Semigroup> => ({ */ export const getEq: (E: Eq) => Eq> = RNEA.getEq +/** + * @category combinators + * @since 2.11.0 + */ +export const getUnionSemigroup = (E: Eq): Semigroup> => { + const unionE = union(E) + return { + concat: (first, second) => unionE(second)(first) + } +} + /** * @category instances * @since 2.7.0 @@ -982,7 +1091,7 @@ export const Comonad: Comonad1 = { */ export const Do: NonEmptyArray<{}> = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 @@ -1056,10 +1165,82 @@ export const max: (ord: Ord) => (nea: NonEmptyArray) => A = RNEA.max */ export const concatAll = (S: Semigroup) => (as: NonEmptyArray): A => as.reduce(S.concat) +/** + * Break an `Array` into its first element and remaining elements. + * + * @category destructors + * @since 2.11.0 + */ +export const matchLeft = (f: (head: A, tail: Array) => B) => (as: NonEmptyArray): B => f(head(as), tail(as)) + +/** + * Break an `Array` into its initial elements and the last element. + * + * @category destructors + * @since 2.11.0 + */ +export const matchRight = (f: (init: Array, last: A) => B) => (as: NonEmptyArray): B => + f(init(as), last(as)) + +/** + * Apply a function to the head, creating a new `NonEmptyArray`. + * + * @since 2.11.0 + */ +export const modifyHead = (f: Endomorphism) => (as: NonEmptyArray): NonEmptyArray => [ + f(head(as)), + ...tail(as) +] + +/** + * Change the head, creating a new `NonEmptyArray`. + * + * @category combinators + * @since 2.11.0 + */ +export const updateHead = (a: A): ((as: NonEmptyArray) => NonEmptyArray) => modifyHead(() => a) + +/** + * Apply a function to the last element, creating a new `NonEmptyArray`. + * + * @since 2.11.0 + */ +export const modifyLast = (f: Endomorphism) => (as: NonEmptyArray): NonEmptyArray => + pipe(init(as), append(f(last(as)))) + +/** + * Change the last element, creating a new `NonEmptyArray`. + * + * @category combinators + * @since 2.11.0 + */ +export const updateLast = (a: A): ((as: NonEmptyArray) => NonEmptyArray) => modifyLast(() => a) + // ------------------------------------------------------------------------------------- // deprecated // ------------------------------------------------------------------------------------- +// tslint:disable: deprecation + +/** + * This is just `sort` followed by `group`. + * + * @category combinators + * @since 2.0.0 + * @deprecated + */ +export function groupSort( + O: Ord +): { + (as: NonEmptyArray): NonEmptyArray> + (as: Array): Array> +} +export function groupSort(O: Ord): (as: Array) => Array> { + const sortO = sort(O) + const groupO = group(O) + return (as) => (isNonEmpty(as) ? groupO(sortO(as)) : []) +} + /** * Use [`filter`](./Array.ts.html#filter) instead. * @@ -1068,9 +1249,9 @@ export const concatAll = (S: Semigroup) => (as: NonEmptyArray): A => as * @deprecated */ export function filter(refinement: Refinement): (as: NonEmptyArray) => Option> +export function filter(predicate: Predicate): (bs: NonEmptyArray) => Option> export function filter(predicate: Predicate): (as: NonEmptyArray) => Option> export function filter(predicate: Predicate): (as: NonEmptyArray) => Option> { - // tslint:disable-next-line: deprecation return filterWithIndex((_, a) => predicate(a)) } diff --git a/src/Option.ts b/src/Option.ts index a9584b75e..68f731991 100644 --- a/src/Option.ts +++ b/src/Option.ts @@ -29,20 +29,26 @@ import { Eq } from './Eq' import { Extend1 } from './Extend' import { Filterable1 } from './Filterable' import { Foldable1 } from './Foldable' -import { constNull, constUndefined, flow, identity, Lazy, pipe, Predicate, Refinement } from './function' +import { chainEitherK as chainEitherK_, FromEither1, fromEitherK as fromEitherK_ } from './FromEither' +import { constNull, constUndefined, flow, identity, Lazy, pipe } from './function' import { bindTo as bindTo_, flap as flap_, Functor1 } from './Functor' import { HKT } from './HKT' import * as _ from './internal' import { Monad1 } from './Monad' import { MonadThrow1 } from './MonadThrow' import { Monoid } from './Monoid' +import { NonEmptyArray } from './NonEmptyArray' import { Ord } from './Ord' import { Pointed1 } from './Pointed' -import { Semigroup } from './Semigroup' +import { not, Predicate } from './Predicate' +import { ReadonlyNonEmptyArray } from './ReadonlyNonEmptyArray' +import { Refinement } from './Refinement' +import { first, last, Semigroup } from './Semigroup' import { Separated, separated } from './Separated' import { Show } from './Show' import { PipeableTraverse1, Traversable1 } from './Traversable' -import { PipeableWilt1, PipeableWither1, Witherable1 } from './Witherable' +import { PipeableWilt1, PipeableWither1, wiltDefault, Witherable1, witherDefault } from './Witherable' +import { Zero1, guard as guard_ } from './Zero' // ------------------------------------------------------------------------------------- // model @@ -71,38 +77,6 @@ export interface Some { */ export type Option = None | Some -// ------------------------------------------------------------------------------------- -// guards -// ------------------------------------------------------------------------------------- - -/** - * Returns `true` if the option is an instance of `Some`, `false` otherwise. - * - * @example - * import { some, none, isSome } from 'fp-ts/Option' - * - * assert.strictEqual(isSome(some(1)), true) - * assert.strictEqual(isSome(none), false) - * - * @category guards - * @since 2.0.0 - */ -export const isSome: (fa: Option) => fa is Some = _.isSome - -/** - * Returns `true` if the option is `None`, `false` otherwise. - * - * @example - * import { some, none, isNone } from 'fp-ts/Option' - * - * assert.strictEqual(isNone(some(1)), false) - * assert.strictEqual(isNone(none), true) - * - * @category guards - * @since 2.0.0 - */ -export const isNone = (fa: Option): fa is None => fa._tag === 'None' - // ------------------------------------------------------------------------------------- // constructors // ------------------------------------------------------------------------------------- @@ -113,7 +87,7 @@ export const isNone = (fa: Option): fa is None => fa._tag === 'None' * @category constructors * @since 2.0.0 */ -export const none: Option = { _tag: 'None' } +export const none: Option = _.none /** * Constructs a `Some`. Represents an optional value that exists. @@ -121,7 +95,7 @@ export const none: Option = { _tag: 'None' } * @category constructors * @since 2.0.0 */ -export const some = (a: A): Option => ({ _tag: 'Some', value: a }) +export const some: (a: A) => Option = _.some /** * Returns a *smart constructor* based on the given predicate. @@ -138,6 +112,7 @@ export const some = (a: A): Option => ({ _tag: 'Some', value: a }) * @since 2.0.0 */ export function fromPredicate(refinement: Refinement): (a: A) => Option +export function fromPredicate(predicate: Predicate): (b: B) => Option export function fromPredicate(predicate: Predicate): (a: A) => Option export function fromPredicate(predicate: Predicate): (a: A) => Option { return (a) => (predicate(a) ? some(a) : none) @@ -156,9 +131,7 @@ export function fromPredicate(predicate: Predicate): (a: A) => Option { * @category constructors * @since 2.0.0 */ -export function getLeft(ma: Either): Option { - return ma._tag === 'Right' ? none : some(ma.left) -} +export const getLeft = (ma: Either): Option => (ma._tag === 'Right' ? none : some(ma.left)) /** * Returns the `Right` value of an `Either` if possible. @@ -173,396 +146,272 @@ export function getLeft(ma: Either): Option { * @category constructors * @since 2.0.0 */ -export function getRight(ma: Either): Option { - return ma._tag === 'Left' ? none : some(ma.right) -} - -/** - * Transforms an `Either` to an `Option` discarding the error. - * - * Alias of [getRight](#getright) - * - * @category constructors - * @since 2.0.0 - */ -export const fromEither: (ma: Either) => Option = getRight +export const getRight = (ma: Either): Option => (ma._tag === 'Left' ? none : some(ma.right)) // ------------------------------------------------------------------------------------- -// destructors +// non-pipeables // ------------------------------------------------------------------------------------- -/** - * Less strict version of [`match`](#match). - * - * @category destructors - * @since 2.10.0 - */ -export const matchW = (onNone: Lazy, onSome: (a: A) => C) => (ma: Option): B | C => - isNone(ma) ? onNone() : onSome(ma.value) +const _map: Monad1['map'] = (fa, f) => pipe(fa, map(f)) +const _ap: Monad1['ap'] = (fab, fa) => pipe(fab, ap(fa)) +const _chain: Monad1['chain'] = (ma, f) => pipe(ma, chain(f)) +const _reduce: Foldable1['reduce'] = (fa, b, f) => pipe(fa, reduce(b, f)) +const _foldMap: Foldable1['foldMap'] = (M) => { + const foldMapM = foldMap(M) + return (fa, f) => pipe(fa, foldMapM(f)) +} +const _reduceRight: Foldable1['reduceRight'] = (fa, b, f) => pipe(fa, reduceRight(b, f)) +const _traverse: Traversable1['traverse'] = ( + F: ApplicativeHKT +): ((ta: Option, f: (a: A) => HKT) => HKT>) => { + const traverseF = traverse(F) + return (ta, f) => pipe(ta, traverseF(f)) +} +/* istanbul ignore next */ +const _alt: Alt1['alt'] = (fa, that) => pipe(fa, alt(that)) +const _filter: Filterable1['filter'] = (fa: Option, predicate: Predicate) => pipe(fa, filter(predicate)) +/* istanbul ignore next */ +const _filterMap: Filterable1['filterMap'] = (fa, f) => pipe(fa, filterMap(f)) +/* istanbul ignore next */ +const _extend: Extend1['extend'] = (wa, f) => pipe(wa, extend(f)) +/* istanbul ignore next */ +const _partition: Filterable1['partition'] = (fa: Option, predicate: Predicate) => + pipe(fa, partition(predicate)) +/* istanbul ignore next */ +const _partitionMap: Filterable1['partitionMap'] = (fa, f) => pipe(fa, partitionMap(f)) -/** - * Alias of [`matchW`](#matchw). - * - * @category destructors - * @since 2.10.0 - */ -export const foldW = matchW +// ------------------------------------------------------------------------------------- +// instances +// ------------------------------------------------------------------------------------- /** - * Takes a (lazy) default value, a function, and an `Option` value, if the `Option` value is `None` the default value is - * returned, otherwise the function is applied to the value inside the `Some` and the result is returned. - * - * @example - * import { some, none, match } from 'fp-ts/Option' - * import { pipe } from 'fp-ts/function' - * - * assert.strictEqual( - * pipe( - * some(1), - * match(() => 'a none', a => `a some containing ${a}`) - * ), - * 'a some containing 1' - * ) - * - * assert.strictEqual( - * pipe( - * none, - * match(() => 'a none', a => `a some containing ${a}`) - * ), - * 'a none' - * ) - * - * @category destructors - * @since 2.10.0 + * @category instances + * @since 2.0.0 */ -export const match: (onNone: Lazy, onSome: (a: A) => B) => (ma: Option) => B = matchW +export const URI = 'Option' /** - * Alias of [`match`](#match). - * - * @category destructors + * @category instances * @since 2.0.0 */ -export const fold = match +export type URI = typeof URI + +declare module './HKT' { + interface URItoKind { + readonly [URI]: Option + } +} /** - * Less strict version of [`getOrElse`](#getorelse). - * - * @category destructors - * @since 2.6.0 + * @category instances + * @since 2.0.0 */ -export const getOrElseW = (onNone: Lazy) => (ma: Option): A | B => (isNone(ma) ? onNone() : ma.value) +export const getShow = (S: Show): Show> => ({ + show: (ma) => (isNone(ma) ? 'none' : `some(${S.show(ma.value)})`) +}) /** - * Extracts the value out of the structure, if it exists. Otherwise returns the given default value - * * @example - * import { some, none, getOrElse } from 'fp-ts/Option' - * import { pipe } from 'fp-ts/function' + * import { none, some, getEq } from 'fp-ts/Option' + * import * as N from 'fp-ts/number' * - * assert.strictEqual( - * pipe( - * some(1), - * getOrElse(() => 0) - * ), - * 1 - * ) - * assert.strictEqual( - * pipe( - * none, - * getOrElse(() => 0) - * ), - * 0 - * ) + * const E = getEq(N.Eq) + * assert.strictEqual(E.equals(none, none), true) + * assert.strictEqual(E.equals(none, some(1)), false) + * assert.strictEqual(E.equals(some(1), none), false) + * assert.strictEqual(E.equals(some(1), some(2)), false) + * assert.strictEqual(E.equals(some(1), some(1)), true) * - * @category destructors + * @category instances * @since 2.0.0 */ -export const getOrElse: (onNone: Lazy) => (ma: Option) => A = getOrElseW - -// ------------------------------------------------------------------------------------- -// interop -// ------------------------------------------------------------------------------------- +export const getEq = (E: Eq): Eq> => ({ + equals: (x, y) => x === y || (isNone(x) ? isNone(y) : isNone(y) ? false : E.equals(x.value, y.value)) +}) /** - * Constructs a new `Option` from a nullable type. If the value is `null` or `undefined`, returns `None`, otherwise - * returns the value wrapped in a `Some`. + * The `Ord` instance allows `Option` values to be compared with + * `compare`, whenever there is an `Ord` instance for + * the type the `Option` contains. + * + * `None` is considered to be less than any `Some` value. + * * * @example - * import { none, some, fromNullable } from 'fp-ts/Option' + * import { none, some, getOrd } from 'fp-ts/Option' + * import * as N from 'fp-ts/number' * - * assert.deepStrictEqual(fromNullable(undefined), none) - * assert.deepStrictEqual(fromNullable(null), none) - * assert.deepStrictEqual(fromNullable(1), some(1)) + * const O = getOrd(N.Ord) + * assert.strictEqual(O.compare(none, none), 0) + * assert.strictEqual(O.compare(none, some(1)), -1) + * assert.strictEqual(O.compare(some(1), none), 1) + * assert.strictEqual(O.compare(some(1), some(2)), -1) + * assert.strictEqual(O.compare(some(1), some(1)), 0) * - * @category interop + * @category instances * @since 2.0.0 */ -export const fromNullable = (a: A): Option> => (a == null ? none : some(a as NonNullable)) +export const getOrd = (O: Ord): Ord> => ({ + equals: getEq(O).equals, + compare: (x, y) => (x === y ? 0 : isSome(x) ? (isSome(y) ? O.compare(x.value, y.value) : 1) : -1) +}) /** - * Transforms an exception into an `Option`. If `f` throws, returns `None`, otherwise returns the output wrapped in a - * `Some`. + * Monoid returning the left-most non-`None` value. If both operands are `Some`s then the inner values are + * concatenated using the provided `Semigroup` * - * See also [`tryCatchK`](#trycatchk). + * | x | y | concat(x, y) | + * | ------- | ------- | ------------------ | + * | none | none | none | + * | some(a) | none | some(a) | + * | none | some(b) | some(b) | + * | some(a) | some(b) | some(concat(a, b)) | * * @example - * import { none, some, tryCatch } from 'fp-ts/Option' + * import { getMonoid, some, none } from 'fp-ts/Option' + * import { SemigroupSum } from 'fp-ts/number' * - * assert.deepStrictEqual( - * tryCatch(() => { - * throw new Error() - * }), - * none - * ) - * assert.deepStrictEqual(tryCatch(() => 1), some(1)) + * const M = getMonoid(SemigroupSum) + * assert.deepStrictEqual(M.concat(none, none), none) + * assert.deepStrictEqual(M.concat(some(1), none), some(1)) + * assert.deepStrictEqual(M.concat(none, some(1)), some(1)) + * assert.deepStrictEqual(M.concat(some(1), some(2)), some(3)) * - * @category interop + * @category instances * @since 2.0.0 */ -export const tryCatch = (f: Lazy): Option => { - try { - return some(f()) - } catch (e) { - return none - } +export const getMonoid = (S: Semigroup): Monoid> => ({ + concat: (x, y) => (isNone(x) ? y : isNone(y) ? x : some(S.concat(x.value, y.value))), + empty: none +}) + +/** + * @category instance operations + * @since 2.0.0 + */ +export const map: (f: (a: A) => B) => (fa: Option) => Option = (f) => (fa) => + isNone(fa) ? none : some(f(fa.value)) + +/** + * @category instances + * @since 2.7.0 + */ +export const Functor: Functor1 = { + URI, + map: _map } /** - * Converts a function that may throw to one returning a `Option`. - * - * @category interop + * @category instance operations + * @since 2.7.0 + */ +export const of: Pointed1['of'] = some + +/** + * @category instances * @since 2.10.0 */ -export const tryCatchK = , B>(f: (...a: A) => B): ((...a: A) => Option) => (...a) => - tryCatch(() => f(...a)) +export const Pointed: Pointed1 = { + URI, + of +} /** - * Returns a *smart constructor* from a function that returns a nullable value. - * - * @example - * import { fromNullableK, none, some } from 'fp-ts/Option' - * - * const f = (s: string): number | undefined => { - * const n = parseFloat(s) - * return isNaN(n) ? undefined : n - * } - * - * const g = fromNullableK(f) - * - * assert.deepStrictEqual(g('1'), some(1)) - * assert.deepStrictEqual(g('a'), none) - * - * @category interop - * @since 2.9.0 + * @category instance operations + * @since 2.0.0 */ -export const fromNullableK: , B>( - f: (...a: A) => B | null | undefined -) => (...a: A) => Option> = (f) => flow(f, fromNullable) +export const ap: (fa: Option) => (fab: Option<(a: A) => B>) => Option = (fa) => (fab) => + isNone(fab) ? none : isNone(fa) ? none : some(fab.value(fa.value)) /** - * This is `chain` + `fromNullable`, useful when working with optional values. - * - * @example - * import { some, none, fromNullable, chainNullableK } from 'fp-ts/Option' - * import { pipe } from 'fp-ts/function' - * - * interface Employee { - * readonly company?: { - * readonly address?: { - * readonly street?: { - * readonly name?: string - * } - * } - * } - * } - * - * const employee1: Employee = { company: { address: { street: { name: 'high street' } } } } - * - * assert.deepStrictEqual( - * pipe( - * fromNullable(employee1.company), - * chainNullableK(company => company.address), - * chainNullableK(address => address.street), - * chainNullableK(street => street.name) - * ), - * some('high street') - * ) - * - * const employee2: Employee = { company: { address: { street: {} } } } - * - * assert.deepStrictEqual( - * pipe( - * fromNullable(employee2.company), - * chainNullableK(company => company.address), - * chainNullableK(address => address.street), - * chainNullableK(street => street.name) - * ), - * none - * ) - * - * @category interop - * @since 2.9.0 + * @category instances + * @since 2.10.0 */ -export const chainNullableK = (f: (a: A) => B | null | undefined) => (ma: Option): Option => - isNone(ma) ? none : fromNullable(f(ma.value)) +export const Apply: Apply1 = { + URI, + map: _map, + ap: _ap +} /** - * Extracts the value out of the structure, if it exists. Otherwise returns `null`. - * - * @example - * import { some, none, toNullable } from 'fp-ts/Option' - * import { pipe } from 'fp-ts/function' - * - * assert.strictEqual( - * pipe( - * some(1), - * toNullable - * ), - * 1 - * ) - * assert.strictEqual( - * pipe( - * none, - * toNullable - * ), - * null - * ) - * - * @category interop - * @since 2.0.0 + * @category instances + * @since 2.7.0 */ -export const toNullable: (ma: Option) => A | null = - /*#__PURE__*/ - match(constNull, identity) +export const Applicative: Applicative1 = { + URI, + map: _map, + ap: _ap, + of +} /** - * Extracts the value out of the structure, if it exists. Otherwise returns `undefined`. - * - * @example - * import { some, none, toUndefined } from 'fp-ts/Option' - * import { pipe } from 'fp-ts/function' - * - * assert.strictEqual( - * pipe( - * some(1), - * toUndefined - * ), - * 1 - * ) - * assert.strictEqual( - * pipe( - * none, - * toUndefined - * ), - * undefined - * ) + * Composes computations in sequence, using the return value of one computation to determine the next computation. * - * @category interop + * @category instance operations * @since 2.0.0 */ -export const toUndefined: (ma: Option) => A | undefined = - /*#__PURE__*/ - match(constUndefined, identity) - -// ------------------------------------------------------------------------------------- -// non-pipeables -// ------------------------------------------------------------------------------------- +export const chain: (f: (a: A) => Option) => (ma: Option) => Option = (f) => (ma) => + isNone(ma) ? none : f(ma.value) -const _map: Monad1['map'] = (fa, f) => pipe(fa, map(f)) -const _ap: Monad1['ap'] = (fab, fa) => pipe(fab, ap(fa)) -const _chain: Monad1['chain'] = (ma, f) => pipe(ma, chain(f)) -const _reduce: Foldable1['reduce'] = (fa, b, f) => pipe(fa, reduce(b, f)) -const _foldMap: Foldable1['foldMap'] = (M) => { - const foldMapM = foldMap(M) - return (fa, f) => pipe(fa, foldMapM(f)) -} -const _reduceRight: Foldable1['reduceRight'] = (fa, b, f) => pipe(fa, reduceRight(b, f)) -const _traverse: Traversable1['traverse'] = ( - F: ApplicativeHKT -): ((ta: Option, f: (a: A) => HKT) => HKT>) => { - const traverseF = traverse(F) - return (ta, f) => pipe(ta, traverseF(f)) -} -/* istanbul ignore next */ -const _alt: Alt1['alt'] = (fa, that) => pipe(fa, alt(that)) -const _filter: Filterable1['filter'] = (fa: Option, predicate: Predicate) => pipe(fa, filter(predicate)) -/* istanbul ignore next */ -const _filterMap: Filterable1['filterMap'] = (fa, f) => pipe(fa, filterMap(f)) -/* istanbul ignore next */ -const _extend: Extend1['extend'] = (wa, f) => pipe(wa, extend(f)) -/* istanbul ignore next */ -const _partition: Filterable1['partition'] = (fa: Option, predicate: Predicate) => - pipe(fa, partition(predicate)) -/* istanbul ignore next */ -const _partitionMap: Filterable1['partitionMap'] = (fa, f) => pipe(fa, partitionMap(f)) -/* istanbul ignore next */ -const _wither: Witherable1['wither'] = ( - F: ApplicativeHKT -): ((fa: Option, f: (a: A) => HKT>) => HKT>) => { - const witherF = wither(F) - return (fa, f) => pipe(fa, witherF(f)) -} -/* istanbul ignore next */ -const _wilt: Witherable1['wilt'] = ( - F: ApplicativeHKT -): ((fa: Option, f: (a: A) => HKT>) => HKT, Option>>) => { - const wiltF = wilt(F) - return (fa, f) => pipe(fa, wiltF(f)) +/** + * @category instances + * @since 2.10.0 + */ +export const Chain: Chain1 = { + URI, + map: _map, + ap: _ap, + chain: _chain } -// ------------------------------------------------------------------------------------- -// type class members -// ------------------------------------------------------------------------------------- - /** - * `map` can be used to turn functions `(a: A) => B` into functions `(fa: F) => F` whose argument and return types - * use the type constructor `F` to represent some computational context. - * - * @category Functor - * @since 2.0.0 + * @category instances + * @since 2.7.0 */ -export const map: (f: (a: A) => B) => (fa: Option) => Option = (f) => (fa) => - isNone(fa) ? none : some(f(fa.value)) +export const Monad: Monad1 = { + URI, + map: _map, + ap: _ap, + of, + chain: _chain +} /** - * Apply a function to an argument under a type constructor. - * - * @category Apply + * @category instance operations * @since 2.0.0 */ -export const ap: (fa: Option) => (fab: Option<(a: A) => B>) => Option = (fa) => (fab) => - isNone(fab) ? none : isNone(fa) ? none : some(fab.value(fa.value)) +export const reduce: (b: B, f: (b: B, a: A) => B) => (fa: Option) => B = (b, f) => (fa) => + isNone(fa) ? b : f(b, fa.value) /** - * @category Pointed - * @since 2.7.0 + * @category instance operations + * @since 2.0.0 */ -export const of: Pointed1['of'] = some +export const foldMap: (M: Monoid) => (f: (a: A) => M) => (fa: Option) => M = (M) => (f) => (fa) => + isNone(fa) ? M.empty : f(fa.value) /** - * Composes computations in sequence, using the return value of one computation to determine the next computation. - * - * @category Monad + * @category instance operations * @since 2.0.0 */ -export const chain: (f: (a: A) => Option) => (ma: Option) => Option = (f) => (ma) => - isNone(ma) ? none : f(ma.value) +export const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: Option) => B = (b, f) => (fa) => + isNone(fa) ? b : f(fa.value, b) /** - * Derivable from `Chain`. - * - * @category combinators - * @since 2.0.0 + * @category instances + * @since 2.7.0 */ -export const flatten: (mma: Option>) => Option = - /*#__PURE__*/ - chain(identity) +export const Foldable: Foldable1 = { + URI, + reduce: _reduce, + foldMap: _foldMap, + reduceRight: _reduceRight +} /** * Less strict version of [`alt`](#alt). * - * @category Alt + * @category instance operations * @since 2.9.0 */ export const altW: (that: Lazy>) => (fa: Option) => Option = (that) => (fa) => @@ -593,110 +442,132 @@ export const altW: (that: Lazy>) => (fa: Option) => Option(that: Lazy>) => (fa: Option) => Option = altW /** - * @category Alternative + * @category instances * @since 2.7.0 */ -export const zero: Alternative1['zero'] = () => none +export const Alt: Alt1 = { + URI, + map: _map, + alt: _alt +} /** - * @category MonadThrow + * @category instance operations * @since 2.7.0 */ -export const throwError: MonadThrow1['throwError'] = () => none +export const zero: Zero1['zero'] = () => none /** - * @category Extend - * @since 2.0.0 + * @category instances + * @since 2.11.0 */ -export const extend: (f: (wa: Option) => B) => (wa: Option) => Option = (f) => (wa) => - isNone(wa) ? none : some(f(wa)) +export const Zero: Zero1 = { + URI, + zero +} /** - * Derivable from `Extend`. - * - * @category combinators - * @since 2.0.0 + * @category constructors + * @since 2.11.0 */ -export const duplicate: (ma: Option) => Option> = +export const guard = /*#__PURE__*/ - extend(identity) + guard_(Zero, Pointed) /** - * @category Foldable - * @since 2.0.0 + * @category instances + * @since 2.7.0 */ -export const reduce: (b: B, f: (b: B, a: A) => B) => (fa: Option) => B = (b, f) => (fa) => - isNone(fa) ? b : f(b, fa.value) +export const Alternative: Alternative1 = { + URI, + map: _map, + ap: _ap, + of, + alt: _alt, + zero +} /** - * @category Foldable + * @category instance operations * @since 2.0.0 */ -export const foldMap: (M: Monoid) => (f: (a: A) => M) => (fa: Option) => M = (M) => (f) => (fa) => - isNone(fa) ? M.empty : f(fa.value) +export const extend: (f: (wa: Option) => B) => (wa: Option) => Option = (f) => (wa) => + isNone(wa) ? none : some(f(wa)) /** - * @category Foldable - * @since 2.0.0 + * @category instances + * @since 2.7.0 */ -export const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: Option) => B = (b, f) => (fa) => - isNone(fa) ? b : f(fa.value, b) +export const Extend: Extend1 = { + URI, + map: _map, + extend: _extend +} /** - * @category Compactable + * @category instance operations * @since 2.0.0 */ -export const compact: (fa: Option>) => Option = flatten +export const compact: (fa: Option>) => Option = + /*#__PURE__*/ + chain(identity) const defaultSeparated = /*#__PURE__*/ separated(none, none) /** - * @category Compactable + * @category instance operations * @since 2.0.0 */ export const separate: (ma: Option>) => Separated, Option> = (ma) => isNone(ma) ? defaultSeparated : separated(getLeft(ma.value), getRight(ma.value)) /** - * @category Filterable + * @category instances + * @since 2.7.0 + */ +export const Compactable: Compactable1 = { + URI, + compact, + separate +} + +/** + * @category instance operations * @since 2.0.0 */ export const filter: { (refinement: Refinement): (fa: Option) => Option + (predicate: Predicate): (fb: Option) => Option (predicate: Predicate): (fa: Option) => Option } = (predicate: Predicate) => (fa: Option) => (isNone(fa) ? none : predicate(fa.value) ? fa : none) /** - * @category Filterable + * @category instance operations * @since 2.0.0 */ export const filterMap: (f: (a: A) => Option) => (fa: Option) => Option = (f) => (fa) => isNone(fa) ? none : f(fa.value) /** - * @category Filterable + * @category instance operations * @since 2.0.0 */ export const partition: { (refinement: Refinement): (fa: Option) => Separated, Option> + (predicate: Predicate): (fb: Option) => Separated, Option> (predicate: Predicate): (fa: Option) => Separated, Option> -} = (predicate: Predicate) => (fa: Option) => { - return separated( - _filter(fa, (a) => !predicate(a)), - _filter(fa, predicate) - ) -} +} = (predicate: Predicate) => (fa: Option) => separated(_filter(fa, not(predicate)), _filter(fa, predicate)) /** - * @category Filterable + * @category instance operations * @since 2.0.0 */ export const partitionMap: ( @@ -704,7 +575,22 @@ export const partitionMap: ( ) => (fa: Option) => Separated, Option> = (f) => flow(map(f), separate) /** - * @category Traversable + * @category instances + * @since 2.7.0 + */ +export const Filterable: Filterable1 = { + URI, + map: _map, + compact, + separate, + filter: _filter, + filterMap: _filterMap, + partition: _partition, + partitionMap: _partitionMap +} + +/** + * @category instance operations * @since 2.6.3 */ export const traverse: PipeableTraverse1 = (F: ApplicativeHKT) => (f: (a: A) => HKT) => ( @@ -712,7 +598,7 @@ export const traverse: PipeableTraverse1 = (F: ApplicativeHKT) => > => (isNone(ta) ? F.of(none) : F.map(f(ta.value), some)) /** - * @category Traversable + * @category instance operations * @since 2.6.3 */ export const sequence: Traversable1['sequence'] = (F: ApplicativeHKT) => ( @@ -720,201 +606,237 @@ export const sequence: Traversable1['sequence'] = (F: ApplicativeHKT) ): HKT> => (isNone(ta) ? F.of(none) : F.map(ta.value, some)) /** - * @category Witherable - * @since 2.6.5 + * @category instances + * @since 2.7.0 */ -export const wither: PipeableWither1 = (F: ApplicativeHKT) => (f: (a: A) => HKT>) => ( - fa: Option -): HKT> => (isNone(fa) ? F.of(none) : f(fa.value)) +export const Traversable: Traversable1 = { + URI, + map: _map, + reduce: _reduce, + foldMap: _foldMap, + reduceRight: _reduceRight, + traverse: _traverse, + sequence +} + +const _wither: Witherable1['wither'] = + /*#__PURE__*/ + witherDefault(Traversable, Compactable) + +const _wilt: Witherable1['wilt'] = + /*#__PURE__*/ + wiltDefault(Traversable, Compactable) /** - * @category Witherable + * @category instance operations * @since 2.6.5 */ -export const wilt: PipeableWilt1 = (F: ApplicativeHKT) => (f: (a: A) => HKT>) => ( - fa: Option -): HKT, Option>> => { - return isNone(fa) ? F.of(defaultSeparated) : F.map(f(fa.value), (e) => separated(getLeft(e), getRight(e))) +export const wither: PipeableWither1 = ( + F: ApplicativeHKT +): ((f: (a: A) => HKT>) => (fa: Option) => HKT>) => { + const _witherF = _wither(F) + return (f) => (fa) => _witherF(fa, f) } -// ------------------------------------------------------------------------------------- -// instances -// ------------------------------------------------------------------------------------- - /** - * @category instances - * @since 2.0.0 + * @category instance operations + * @since 2.6.5 */ -export const URI = 'Option' +export const wilt: PipeableWilt1 = ( + F: ApplicativeHKT +): ((f: (a: A) => HKT>) => (fa: Option) => HKT, Option>>) => { + const _wiltF = _wilt(F) + return (f) => (fa) => _wiltF(fa, f) +} /** * @category instances - * @since 2.0.0 + * @since 2.7.0 */ -export type URI = typeof URI - -declare module './HKT' { - interface URItoKind { - readonly [URI]: Option - } +export const Witherable: Witherable1 = { + URI, + map: _map, + reduce: _reduce, + foldMap: _foldMap, + reduceRight: _reduceRight, + traverse: _traverse, + sequence, + compact, + separate, + filter: _filter, + filterMap: _filterMap, + partition: _partition, + partitionMap: _partitionMap, + wither: _wither, + wilt: _wilt } +/** + * @category instance operations + * @since 2.7.0 + */ +export const throwError: MonadThrow1['throwError'] = () => none + /** * @category instances - * @since 2.0.0 + * @since 2.7.0 */ -export function getShow(S: Show): Show> { - return { - show: (ma) => (isNone(ma) ? 'none' : `some(${S.show(ma.value)})`) - } +export const MonadThrow: MonadThrow1 = { + URI, + map: _map, + ap: _ap, + of, + chain: _chain, + throwError } /** - * @example - * import { none, some, getEq } from 'fp-ts/Option' - * import * as N from 'fp-ts/number' + * Transforms an `Either` to an `Option` discarding the error. * - * const E = getEq(N.Eq) - * assert.strictEqual(E.equals(none, none), true) - * assert.strictEqual(E.equals(none, some(1)), false) - * assert.strictEqual(E.equals(some(1), none), false) - * assert.strictEqual(E.equals(some(1), some(2)), false) - * assert.strictEqual(E.equals(some(1), some(1)), true) + * Alias of [getRight](#getright) * - * @category instances + * @category natural transformations * @since 2.0.0 */ -export function getEq(E: Eq): Eq> { - return { - equals: (x, y) => x === y || (isNone(x) ? isNone(y) : isNone(y) ? false : E.equals(x.value, y.value)) - } +export const fromEither: FromEither1['fromEither'] = getRight + +/** + * @category instances + * @since 2.11.0 + */ +export const FromEither: FromEither1 = { + URI, + fromEither } + +// ------------------------------------------------------------------------------------- +// refinements +// ------------------------------------------------------------------------------------- + /** - * The `Ord` instance allows `Option` values to be compared with - * `compare`, whenever there is an `Ord` instance for - * the type the `Option` contains. - * - * `None` is considered to be less than any `Some` value. - * + * Returns `true` if the option is an instance of `Some`, `false` otherwise. * * @example - * import { none, some, getOrd } from 'fp-ts/Option' - * import * as N from 'fp-ts/number' + * import { some, none, isSome } from 'fp-ts/Option' * - * const O = getOrd(N.Ord) - * assert.strictEqual(O.compare(none, none), 0) - * assert.strictEqual(O.compare(none, some(1)), -1) - * assert.strictEqual(O.compare(some(1), none), 1) - * assert.strictEqual(O.compare(some(1), some(2)), -1) - * assert.strictEqual(O.compare(some(1), some(1)), 0) + * assert.strictEqual(isSome(some(1)), true) + * assert.strictEqual(isSome(none), false) * - * @category instances + * @category refinements * @since 2.0.0 */ -export function getOrd(O: Ord): Ord> { - return { - equals: getEq(O).equals, - compare: (x, y) => (x === y ? 0 : isSome(x) ? (isSome(y) ? O.compare(x.value, y.value) : 1) : -1) - } -} +export const isSome: (fa: Option) => fa is Some = _.isSome /** - * Monoid returning the left-most non-`None` value - * - * | x | y | concat(x, y) | - * | ------- | ------- | ------------ | - * | none | none | none | - * | some(a) | none | some(a) | - * | none | some(a) | some(a) | - * | some(a) | some(b) | some(a) | + * Returns `true` if the option is `None`, `false` otherwise. * * @example - * import { getFirstMonoid, some, none } from 'fp-ts/Option' + * import { some, none, isNone } from 'fp-ts/Option' * - * const M = getFirstMonoid() - * assert.deepStrictEqual(M.concat(none, none), none) - * assert.deepStrictEqual(M.concat(some(1), none), some(1)) - * assert.deepStrictEqual(M.concat(none, some(1)), some(1)) - * assert.deepStrictEqual(M.concat(some(1), some(2)), some(1)) + * assert.strictEqual(isNone(some(1)), false) + * assert.strictEqual(isNone(none), true) * - * @category instances + * @category refinements * @since 2.0.0 */ -export function getFirstMonoid(): Monoid> { - return { - concat: (x, y) => (isNone(x) ? y : x), - empty: none - } -} +export const isNone = (fa: Option): fa is None => fa._tag === 'None' + +// ------------------------------------------------------------------------------------- +// destructors +// ------------------------------------------------------------------------------------- /** - * Monoid returning the right-most non-`None` value + * Less strict version of [`match`](#match). * - * | x | y | concat(x, y) | - * | ------- | ------- | ------------ | - * | none | none | none | - * | some(a) | none | some(a) | - * | none | some(a) | some(a) | - * | some(a) | some(b) | some(b) | + * @category destructors + * @since 2.10.0 + */ +export const matchW = (onNone: Lazy, onSome: (a: A) => C) => (ma: Option): B | C => + isNone(ma) ? onNone() : onSome(ma.value) + +/** + * Alias of [`matchW`](#matchw). + * + * @category destructors + * @since 2.10.0 + */ +export const foldW = matchW + +/** + * Takes a (lazy) default value, a function, and an `Option` value, if the `Option` value is `None` the default value is + * returned, otherwise the function is applied to the value inside the `Some` and the result is returned. * * @example - * import { getLastMonoid, some, none } from 'fp-ts/Option' + * import { some, none, match } from 'fp-ts/Option' + * import { pipe } from 'fp-ts/function' * - * const M = getLastMonoid() - * assert.deepStrictEqual(M.concat(none, none), none) - * assert.deepStrictEqual(M.concat(some(1), none), some(1)) - * assert.deepStrictEqual(M.concat(none, some(1)), some(1)) - * assert.deepStrictEqual(M.concat(some(1), some(2)), some(2)) + * assert.strictEqual( + * pipe( + * some(1), + * match(() => 'a none', a => `a some containing ${a}`) + * ), + * 'a some containing 1' + * ) * - * @category instances + * assert.strictEqual( + * pipe( + * none, + * match(() => 'a none', a => `a some containing ${a}`) + * ), + * 'a none' + * ) + * + * @category destructors + * @since 2.10.0 + */ +export const match: (onNone: Lazy, onSome: (a: A) => B) => (ma: Option) => B = matchW + +/** + * Alias of [`match`](#match). + * + * @category destructors * @since 2.0.0 */ -export function getLastMonoid(): Monoid> { - return { - concat: (x, y) => (isNone(y) ? x : y), - empty: none - } -} +export const fold = match /** - * Monoid returning the left-most non-`None` value. If both operands are `Some`s then the inner values are - * concatenated using the provided `Semigroup` + * Less strict version of [`getOrElse`](#getorelse). * - * | x | y | concat(x, y) | - * | ------- | ------- | ------------------ | - * | none | none | none | - * | some(a) | none | some(a) | - * | none | some(a) | some(a) | - * | some(a) | some(b) | some(concat(a, b)) | + * @category destructors + * @since 2.6.0 + */ +export const getOrElseW = (onNone: Lazy) => (ma: Option): A | B => (isNone(ma) ? onNone() : ma.value) + +/** + * Extracts the value out of the structure, if it exists. Otherwise returns the given default value * * @example - * import { getMonoid, some, none } from 'fp-ts/Option' - * import { SemigroupSum } from 'fp-ts/number' + * import { some, none, getOrElse } from 'fp-ts/Option' + * import { pipe } from 'fp-ts/function' * - * const M = getMonoid(SemigroupSum) - * assert.deepStrictEqual(M.concat(none, none), none) - * assert.deepStrictEqual(M.concat(some(1), none), some(1)) - * assert.deepStrictEqual(M.concat(none, some(1)), some(1)) - * assert.deepStrictEqual(M.concat(some(1), some(2)), some(3)) + * assert.strictEqual( + * pipe( + * some(1), + * getOrElse(() => 0) + * ), + * 1 + * ) + * assert.strictEqual( + * pipe( + * none, + * getOrElse(() => 0) + * ), + * 0 + * ) * - * @category instances + * @category destructors * @since 2.0.0 */ -export function getMonoid(S: Semigroup): Monoid> { - return { - concat: (x, y) => (isNone(x) ? y : isNone(y) ? x : some(S.concat(x.value, y.value))), - empty: none - } -} +export const getOrElse: (onNone: Lazy) => (ma: Option) => A = getOrElseW -/** - * @category instances - * @since 2.7.0 - */ -export const Functor: Functor1 = { - URI, - map: _map -} +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- /** * Derivable from `Functor`. @@ -926,25 +848,6 @@ export const flap = /*#__PURE__*/ flap_(Functor) -/** - * @category instances - * @since 2.10.0 - */ -export const Pointed: Pointed1 = { - URI, - of -} - -/** - * @category instances - * @since 2.10.0 - */ -export const Apply: Apply1 = { - URI, - map: _map, - ap: _ap -} - /** * Combine two effectful actions, keeping only the result of the first. * @@ -970,38 +873,12 @@ export const apSecond = apSecond_(Apply) /** - * @category instances - * @since 2.7.0 - */ -export const Applicative: Applicative1 = { - URI, - map: _map, - ap: _ap, - of -} - -/** - * @category instances - * @since 2.10.0 + * Derivable from `Chain`. + * + * @category combinators + * @since 2.0.0 */ -export const Chain: Chain1 = { - URI, - map: _map, - ap: _ap, - chain: _chain -} - -/** - * @category instances - * @since 2.7.0 - */ -export const Monad: Monad1 = { - URI, - map: _map, - ap: _ap, - of, - chain: _chain -} +export const flatten: (mma: Option>) => Option = compact /** * Composes computations in sequence, using the return value of one computation to determine the next computation and @@ -1017,122 +894,215 @@ export const chainFirst = chainFirst_(Chain) /** - * @category instances - * @since 2.7.0 + * Derivable from `Extend`. + * + * @category combinators + * @since 2.0.0 */ -export const Foldable: Foldable1 = { - URI, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight -} +export const duplicate: (ma: Option) => Option> = + /*#__PURE__*/ + extend(identity) /** - * @category instances - * @since 2.7.0 + * @category combinators + * @since 2.11.0 */ -export const Alt: Alt1 = { - URI, - map: _map, - alt: _alt -} +export const fromEitherK = + /*#__PURE__*/ + fromEitherK_(FromEither) /** - * @category instances - * @since 2.7.0 + * @category combinators + * @since 2.11.0 */ -export const Alternative: Alternative1 = { - URI, - map: _map, - ap: _ap, - of, - alt: _alt, - zero -} +export const chainEitherK = + /*#__PURE__*/ + chainEitherK_(FromEither, Chain) + +// ------------------------------------------------------------------------------------- +// interop +// ------------------------------------------------------------------------------------- /** - * @category instances - * @since 2.7.0 + * Constructs a new `Option` from a nullable type. If the value is `null` or `undefined`, returns `None`, otherwise + * returns the value wrapped in a `Some`. + * + * @example + * import { none, some, fromNullable } from 'fp-ts/Option' + * + * assert.deepStrictEqual(fromNullable(undefined), none) + * assert.deepStrictEqual(fromNullable(null), none) + * assert.deepStrictEqual(fromNullable(1), some(1)) + * + * @category interop + * @since 2.0.0 */ -export const Extend: Extend1 = { - URI, - map: _map, - extend: _extend -} +export const fromNullable = (a: A): Option> => (a == null ? none : some(a as NonNullable)) /** - * @category instances - * @since 2.7.0 + * Transforms an exception into an `Option`. If `f` throws, returns `None`, otherwise returns the output wrapped in a + * `Some`. + * + * See also [`tryCatchK`](#trycatchk). + * + * @example + * import { none, some, tryCatch } from 'fp-ts/Option' + * + * assert.deepStrictEqual( + * tryCatch(() => { + * throw new Error() + * }), + * none + * ) + * assert.deepStrictEqual(tryCatch(() => 1), some(1)) + * + * @category interop + * @since 2.0.0 */ -export const Compactable: Compactable1 = { - URI, - compact, - separate +export const tryCatch = (f: Lazy): Option => { + try { + return some(f()) + } catch (e) { + return none + } } /** - * @category instances - * @since 2.7.0 + * Converts a function that may throw to one returning a `Option`. + * + * @category interop + * @since 2.10.0 + */ +export const tryCatchK = , B>(f: (...a: A) => B): ((...a: A) => Option) => (...a) => + tryCatch(() => f(...a)) + +/** + * Returns a *smart constructor* from a function that returns a nullable value. + * + * @example + * import { fromNullableK, none, some } from 'fp-ts/Option' + * + * const f = (s: string): number | undefined => { + * const n = parseFloat(s) + * return isNaN(n) ? undefined : n + * } + * + * const g = fromNullableK(f) + * + * assert.deepStrictEqual(g('1'), some(1)) + * assert.deepStrictEqual(g('a'), none) + * + * @category interop + * @since 2.9.0 */ -export const Filterable: Filterable1 = { - URI, - map: _map, - compact, - separate, - filter: _filter, - filterMap: _filterMap, - partition: _partition, - partitionMap: _partitionMap -} +export const fromNullableK: , B>( + f: (...a: A) => B | null | undefined +) => (...a: A) => Option> = (f) => flow(f, fromNullable) /** - * @category instances - * @since 2.7.0 + * This is `chain` + `fromNullable`, useful when working with optional values. + * + * @example + * import { some, none, fromNullable, chainNullableK } from 'fp-ts/Option' + * import { pipe } from 'fp-ts/function' + * + * interface Employee { + * readonly company?: { + * readonly address?: { + * readonly street?: { + * readonly name?: string + * } + * } + * } + * } + * + * const employee1: Employee = { company: { address: { street: { name: 'high street' } } } } + * + * assert.deepStrictEqual( + * pipe( + * fromNullable(employee1.company), + * chainNullableK(company => company.address), + * chainNullableK(address => address.street), + * chainNullableK(street => street.name) + * ), + * some('high street') + * ) + * + * const employee2: Employee = { company: { address: { street: {} } } } + * + * assert.deepStrictEqual( + * pipe( + * fromNullable(employee2.company), + * chainNullableK(company => company.address), + * chainNullableK(address => address.street), + * chainNullableK(street => street.name) + * ), + * none + * ) + * + * @category interop + * @since 2.9.0 */ -export const Traversable: Traversable1 = { - URI, - map: _map, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight, - traverse: _traverse, - sequence -} +export const chainNullableK = (f: (a: A) => B | null | undefined) => (ma: Option): Option => + isNone(ma) ? none : fromNullable(f(ma.value)) /** - * @category instances - * @since 2.7.0 + * Extracts the value out of the structure, if it exists. Otherwise returns `null`. + * + * @example + * import { some, none, toNullable } from 'fp-ts/Option' + * import { pipe } from 'fp-ts/function' + * + * assert.strictEqual( + * pipe( + * some(1), + * toNullable + * ), + * 1 + * ) + * assert.strictEqual( + * pipe( + * none, + * toNullable + * ), + * null + * ) + * + * @category interop + * @since 2.0.0 */ -export const Witherable: Witherable1 = { - URI, - map: _map, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight, - traverse: _traverse, - sequence, - compact, - separate, - filter: _filter, - filterMap: _filterMap, - partition: _partition, - partitionMap: _partitionMap, - wither: _wither, - wilt: _wilt -} +export const toNullable: (ma: Option) => A | null = + /*#__PURE__*/ + match(constNull, identity) /** - * @category instances - * @since 2.7.0 + * Extracts the value out of the structure, if it exists. Otherwise returns `undefined`. + * + * @example + * import { some, none, toUndefined } from 'fp-ts/Option' + * import { pipe } from 'fp-ts/function' + * + * assert.strictEqual( + * pipe( + * some(1), + * toUndefined + * ), + * 1 + * ) + * assert.strictEqual( + * pipe( + * none, + * toUndefined + * ), + * undefined + * ) + * + * @category interop + * @since 2.0.0 */ -export const MonadThrow: MonadThrow1 = { - URI, - map: _map, - ap: _ap, - of, - chain: _chain, - throwError -} +export const toUndefined: (ma: Option) => A | undefined = + /*#__PURE__*/ + match(constUndefined, identity) // ------------------------------------------------------------------------------------- // utils @@ -1186,30 +1156,8 @@ export function elem(E: Eq): (a: A, ma: Option) => boolean { * * @since 2.0.0 */ -export function exists(predicate: Predicate): (ma: Option) => boolean { - return (ma) => (isNone(ma) ? false : predicate(ma.value)) -} - -/** - * Returns a `Refinement` (i.e. a custom type guard) from a `Option` returning function. - * This function ensures that a custom type guard definition is type-safe. - * - * ```ts - * import { some, none, getRefinement } from 'fp-ts/Option' - * - * type A = { type: 'A' } - * type B = { type: 'B' } - * type C = A | B - * - * const isA = (c: C): c is A => c.type === 'B' // <= typo but typescript doesn't complain - * const isA = getRefinement(c => (c.type === 'B' ? some(c) : none)) // static error: Type '"B"' is not assignable to type '"A"' - * ``` - * - * @since 2.0.0 - */ -export function getRefinement(getOption: (a: A) => Option): Refinement { - return (a: A): a is B => isSome(getOption(a)) -} +export const exists = (predicate: Predicate) => (ma: Option): boolean => + isNone(ma) ? false : predicate(ma.value) // ------------------------------------------------------------------------------------- // do notation @@ -1220,7 +1168,7 @@ export function getRefinement(getOption: (a: A) => Option): R */ export const Do: Option<{}> = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 @@ -1247,40 +1195,68 @@ export const apS = /*#__PURE__*/ apS_(Apply) +// ------------------------------------------------------------------------------------- +// sequence T +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export const ApT: Option = of(_.emptyReadonlyArray) + // ------------------------------------------------------------------------------------- // array utils // ------------------------------------------------------------------------------------- /** - * Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. * - * @since 2.9.0 + * @since 2.11.0 */ -export const traverseArrayWithIndex = (f: (index: number, a: A) => Option) => ( - as: ReadonlyArray -): Option> => { - const out = [] - for (let i = 0; i < as.length; i++) { - const b = f(i, as[i]) - if (isNone(b)) { +export const traverseReadonlyNonEmptyArrayWithIndex = (f: (index: number, a: A) => Option) => ( + as: ReadonlyNonEmptyArray +): Option> => { + const o = f(0, _.head(as)) + if (isNone(o)) { + return none + } + const out: NonEmptyArray = [o.value] + for (let i = 1; i < as.length; i++) { + const o = f(i, as[i]) + if (isNone(o)) { return none } - out.push(b.value) + out.push(o.value) } return some(out) } /** - * Equivalent to `ReadonlyArray#traverse(Applicative)`. + * Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndex = ( + f: (index: number, a: A) => Option +): ((as: ReadonlyArray) => Option>) => { + const g = traverseReadonlyNonEmptyArrayWithIndex(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + +/** + * @since 2.9.0 + */ +export const traverseArrayWithIndex: ( + f: (index: number, a: A) => Option +) => (as: ReadonlyArray) => Option> = traverseReadonlyArrayWithIndex + +/** * @since 2.9.0 */ export const traverseArray = (f: (a: A) => Option): ((as: ReadonlyArray) => Option>) => - traverseArrayWithIndex((_, a) => f(a)) + traverseReadonlyArrayWithIndex((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(Applicative)`. - * * @since 2.9.0 */ export const sequenceArray: (arr: ReadonlyArray>) => Option> = @@ -1291,6 +1267,18 @@ export const sequenceArray: (arr: ReadonlyArray>) => Option(getOption: (a: A) => Option): Refinement { + return (a: A): a is B => isSome(getOption(a)) +} + /** * Use [`chainNullableK`](#chainnullablek) instead. * @@ -1358,3 +1346,75 @@ export const getApplySemigroup: (S: Semigroup) => Semigroup> = export const getApplyMonoid: (M: Monoid) => Monoid> = /*#__PURE__*/ getApplicativeMonoid(Applicative) + +/** + * Use + * + * ```ts + * import { first } from 'fp-ts/Semigroup' + * import { getMonoid } from 'fp-ts/Option' + * + * getMonoid(first()) + * ``` + * + * instead. + * + * Monoid returning the left-most non-`None` value + * + * | x | y | concat(x, y) | + * | ------- | ------- | ------------ | + * | none | none | none | + * | some(a) | none | some(a) | + * | none | some(b) | some(b) | + * | some(a) | some(b) | some(a) | + * + * @example + * import { getFirstMonoid, some, none } from 'fp-ts/Option' + * + * const M = getFirstMonoid() + * assert.deepStrictEqual(M.concat(none, none), none) + * assert.deepStrictEqual(M.concat(some(1), none), some(1)) + * assert.deepStrictEqual(M.concat(none, some(2)), some(2)) + * assert.deepStrictEqual(M.concat(some(1), some(2)), some(1)) + * + * @category instances + * @since 2.0.0 + * @deprecated + */ +export const getFirstMonoid = (): Monoid> => getMonoid(first()) + +/** + * Use + * + * ```ts + * import { last } from 'fp-ts/Semigroup' + * import { getMonoid } from 'fp-ts/Option' + * + * getMonoid(last()) + * ``` + * + * instead. + * + * Monoid returning the right-most non-`None` value + * + * | x | y | concat(x, y) | + * | ------- | ------- | ------------ | + * | none | none | none | + * | some(a) | none | some(a) | + * | none | some(b) | some(b) | + * | some(a) | some(b) | some(b) | + * + * @example + * import { getLastMonoid, some, none } from 'fp-ts/Option' + * + * const M = getLastMonoid() + * assert.deepStrictEqual(M.concat(none, none), none) + * assert.deepStrictEqual(M.concat(some(1), none), some(1)) + * assert.deepStrictEqual(M.concat(none, some(2)), some(2)) + * assert.deepStrictEqual(M.concat(some(1), some(2)), some(2)) + * + * @category instances + * @since 2.0.0 + * @deprecated + */ +export const getLastMonoid = (): Monoid> => getMonoid(last()) diff --git a/src/OptionT.ts b/src/OptionT.ts index a611aebef..3eb378a26 100644 --- a/src/OptionT.ts +++ b/src/OptionT.ts @@ -10,12 +10,14 @@ import { import { ap as ap_, Apply, Apply1, Apply2, Apply2C, Apply3, Apply3C, Apply4 } from './Apply' import { Chain, Chain1, Chain2, Chain2C, Chain3, Chain3C, Chain4 } from './Chain' import { Either } from './Either' -import { constant, flow, Lazy, pipe, Predicate, Refinement } from './function' +import { constant, flow, Lazy, pipe } from './function' import { Functor, Functor1, Functor2, Functor2C, Functor3, Functor3C, Functor4, map as map_ } from './Functor' import { HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT' import { Monad, Monad1, Monad2, Monad2C, Monad3, Monad3C, Monad4 } from './Monad' import * as O from './Option' import { Pointed, Pointed1, Pointed2, Pointed2C, Pointed3, Pointed3C, Pointed4 } from './Pointed' +import { Predicate } from './Predicate' +import { Refinement } from './Refinement' import Option = O.Option @@ -243,48 +245,56 @@ export function fromPredicate( F: Pointed4 ): { (refinement: Refinement): (a: A) => Kind4> + (predicate: Predicate): (b: B) => Kind4> (predicate: Predicate): (a: A) => Kind4> } export function fromPredicate( F: Pointed3 ): { (refinement: Refinement): (a: A) => Kind3> + (predicate: Predicate): (b: B) => Kind3> (predicate: Predicate): (a: A) => Kind3> } export function fromPredicate( F: Pointed3C ): { (refinement: Refinement): (a: A) => Kind3> + (predicate: Predicate): (b: B) => Kind3> (predicate: Predicate): (a: A) => Kind3> } export function fromPredicate( F: Pointed2 ): { (refinement: Refinement): (a: A) => Kind2> + (predicate: Predicate): (b: B) => Kind2> (predicate: Predicate): (a: A) => Kind2> } export function fromPredicate( F: Pointed2C ): { (refinement: Refinement): (a: A) => Kind2> + (predicate: Predicate): (b: B) => Kind2> (predicate: Predicate): (a: A) => Kind2> } export function fromPredicate( F: Pointed1 ): { (refinement: Refinement): (a: A) => Kind> + (predicate: Predicate): (b: B) => Kind> (predicate: Predicate): (a: A) => Kind> } export function fromPredicate( F: Pointed ): { (refinement: Refinement): (a: A) => HKT> + (predicate: Predicate): (b: B) => HKT> (predicate: Predicate): (a: A) => HKT> } export function fromPredicate( F: Pointed ): { (refinement: Refinement): (a: A) => HKT> + (predicate: Predicate): (b: B) => HKT> (predicate: Predicate): (a: A) => HKT> } { return (predicate: Predicate) => (a: A) => F.of(O.fromPredicate(predicate)(a)) diff --git a/src/Ord.ts b/src/Ord.ts index e4f0a2bce..d59f26952 100644 --- a/src/Ord.ts +++ b/src/Ord.ts @@ -11,7 +11,7 @@ */ import { Contravariant1 } from './Contravariant' import { Eq, eqStrict } from './Eq' -import { pipe } from './function' +import { constant, constTrue, pipe } from './function' import { Monoid } from './Monoid' import { Ordering } from './Ordering' import { Semigroup } from './Semigroup' @@ -228,6 +228,20 @@ export const Contravariant: Contravariant1 = { // utils // ------------------------------------------------------------------------------------- +/** + * @since 2.11.0 + */ +export const trivial: Ord = { + equals: constTrue, + compare: constant(0) +} + +/** + * @since 2.11.0 + */ +export const equals = (O: Ord) => (second: A) => (first: A): boolean => + first === second || O.compare(first, second) === 0 + // TODO: curry in v3 /** * Test whether one value is _strictly less than_ another @@ -304,6 +318,8 @@ export const between = (O: Ord): ((low: A, hi: A) => (a: A) => boolean) => // deprecated // ------------------------------------------------------------------------------------- +// tslint:disable: deprecation + /** * Use [`tuple`](#tuple) instead. * @@ -380,7 +396,6 @@ export const ordNumber: Ord = strictOrd export const ordDate: Ord = /*#__PURE__*/ pipe( - // tslint:disable-next-line: deprecation ordNumber, /*#__PURE__*/ contramap((date) => date.valueOf()) diff --git a/src/Predicate.ts b/src/Predicate.ts new file mode 100644 index 000000000..92a27c988 --- /dev/null +++ b/src/Predicate.ts @@ -0,0 +1,114 @@ +/** + * @since 2.11.0 + */ +import { Contravariant1 } from './Contravariant' +import { constFalse, constTrue, flow, pipe } from './function' +import { Monoid } from './Monoid' +import { Semigroup } from './Semigroup' + +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export interface Predicate { + (a: A): boolean +} + +// ------------------------------------------------------------------------------------- +// type class members +// ------------------------------------------------------------------------------------- + +const contramap_: Contravariant1['contramap'] = (predicate, f) => pipe(predicate, contramap(f)) + +/** + * @category Contravariant + * @since 2.11.0 + */ +export const contramap = (f: (b: B) => A) => (predicate: Predicate): Predicate => flow(f, predicate) + +// ------------------------------------------------------------------------------------- +// instances +// ------------------------------------------------------------------------------------- + +/** + * @category instances + * @since 2.11.0 + */ +export const URI = 'Predicate' + +/** + * @category instances + * @since 2.11.0 + */ +export type URI = typeof URI + +declare module './HKT' { + interface URItoKind { + readonly [URI]: Predicate + } +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getSemigroupAny = (): Semigroup> => ({ + concat: (first, second) => pipe(first, or(second)) +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const getMonoidAny = (): Monoid> => ({ + concat: getSemigroupAny().concat, + empty: constFalse +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const getSemigroupAll = (): Semigroup> => ({ + concat: (first, second) => pipe(first, and(second)) +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const getMonoidAll = (): Monoid> => ({ + concat: getSemigroupAll().concat, + empty: constTrue +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const Contravariant: Contravariant1 = { + URI, + contramap: contramap_ +} + +// ------------------------------------------------------------------------------------- +// utils +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export const not = (predicate: Predicate): Predicate => (a) => !predicate(a) + +/** + * @since 2.11.0 + */ +export const or = (second: Predicate) => (first: Predicate): Predicate => (a) => first(a) || second(a) + +/** + * @since 2.11.0 + */ +export const and = (second: Predicate) => (first: Predicate): Predicate => (a) => first(a) && second(a) diff --git a/src/Reader.ts b/src/Reader.ts index 59d1eff69..ef0143309 100644 --- a/src/Reader.ts +++ b/src/Reader.ts @@ -2,19 +2,22 @@ * @since 2.0.0 */ import { Applicative2, getApplicativeMonoid } from './Applicative' -import { apFirst as apFirst_, Apply2, apSecond as apSecond_, apS as apS_, getApplySemigroup } from './Apply' +import { apFirst as apFirst_, Apply2, apS as apS_, apSecond as apSecond_, getApplySemigroup } from './Apply' import { Category2 } from './Category' +import { bind as bind_, Chain2, chainFirst as chainFirst_ } from './Chain' import { Choice2 } from './Choice' import * as E from './Either' import { constant, flow, identity, pipe } from './function' import { bindTo as bindTo_, flap as flap_, Functor2 } from './Functor' -import { bind as bind_, Chain2, chainFirst as chainFirst_ } from './Chain' +import * as _ from './internal' +import { Monad2 } from './Monad' import { Monoid } from './Monoid' +import { NonEmptyArray } from './NonEmptyArray' import { Pointed2 } from './Pointed' import { Profunctor2 } from './Profunctor' +import { ReadonlyNonEmptyArray } from './ReadonlyNonEmptyArray' import { Semigroup } from './Semigroup' import { Strong2 } from './Strong' -import { Monad2 } from './Monad' // ------------------------------------------------------------------------------------- // model @@ -62,6 +65,22 @@ export const asks: (f: (r: R) => A) => Reader = identity export const local: (f: (r2: R2) => R1) => (ma: Reader) => Reader = (f) => (ma) => (r2) => ma(f(r2)) +/** + * Less strict version of [`asksReader`](#asksreader). + * + * @category combinators + * @since 2.11.0 + */ +export const asksReaderW = (f: (r1: R1) => Reader): Reader => (r) => f(r)(r) + +/** + * Effectfully accesses the environment. + * + * @category combinators + * @since 2.11.0 + */ +export const asksReader: (f: (r: R) => Reader) => Reader = asksReaderW + // ------------------------------------------------------------------------------------- // non-pipeables // ------------------------------------------------------------------------------------- @@ -130,15 +149,23 @@ export const chainW: (f: (a: A) => Reader) => (ma: Reader(f: (a: A) => Reader) => (ma: Reader) => Reader = chainW +/** + * Less strict version of [`flatten`](#flatten). + * + * @category combinators + * @since 2.11.0 + */ +export const flattenW: (mma: Reader>) => Reader = + /*#__PURE__*/ + chainW(identity) + /** * Derivable from `Chain`. * * @category combinators * @since 2.0.0 */ -export const flatten: (mma: Reader>) => Reader = - /*#__PURE__*/ - chain(identity) +export const flatten: (mma: Reader>) => Reader = flattenW /** * @category Semigroupoid @@ -176,13 +203,13 @@ export const second: Strong2['second'] = (pbc) => ([a, b]) => [a, pbc(b)] * @category Choice * @since 2.10.0 */ -export const left: Choice2['left'] = (pab) => E.fold((a) => E.left(pab(a)), E.right) +export const left: Choice2['left'] = (pab) => E.fold((a) => _.left(pab(a)), E.right) /** * @category Choice * @since 2.10.0 */ -export const right: Choice2['right'] = (pbc) => E.fold(E.left, (b) => E.right(pbc(b))) +export const right: Choice2['right'] = (pbc) => E.fold(E.left, (b) => _.right(pbc(b))) // ------------------------------------------------------------------------------------- // instances @@ -315,6 +342,18 @@ export const chainFirst = /*#__PURE__*/ chainFirst_(Chain) +/** + * Less strict version of [`chainFirst`](#chainfirst). + * + * Derivable from `Chain`. + * + * @category combinators + * @since 2.11.0 + */ +export const chainFirstW: ( + f: (a: A) => Reader +) => (ma: Reader) => Reader = chainFirst as any + /** * @category instances * @since 2.7.0 @@ -396,7 +435,7 @@ export const bindW: ( */ export const Do: Reader = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 @@ -415,31 +454,61 @@ export const apSW: ( fa: Reader ) => Reader = apS as any +// ------------------------------------------------------------------------------------- +// sequence T +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export const ApT: Reader = of(_.emptyReadonlyArray) + // ------------------------------------------------------------------------------------- // array utils // ------------------------------------------------------------------------------------- +/** + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. + * + * @since 2.11.0 + */ +export const traverseReadonlyNonEmptyArrayWithIndex = (f: (index: number, a: A) => Reader) => ( + as: ReadonlyNonEmptyArray +): Reader> => (r) => { + const out: NonEmptyArray = [f(0, _.head(as))(r)] + for (let i = 1; i < as.length; i++) { + out.push(f(i, as[i])(r)) + } + return out +} + /** * Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndex = ( + f: (index: number, a: A) => Reader +): ((as: ReadonlyArray) => Reader>) => { + const g = traverseReadonlyNonEmptyArrayWithIndex(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + +/** * @since 2.9.0 */ -export const traverseArrayWithIndex = (f: (index: number, a: A) => Reader) => ( - as: ReadonlyArray -): Reader> => (r) => as.map((x, i) => f(i, x)(r)) +export const traverseArrayWithIndex: ( + f: (index: number, a: A) => Reader +) => (as: ReadonlyArray) => Reader> = traverseReadonlyArrayWithIndex /** - * Equivalent to `ReadonlyArray#traverse(Applicative)`. - * * @since 2.9.0 */ export const traverseArray = ( f: (a: A) => Reader -): ((as: ReadonlyArray) => Reader>) => traverseArrayWithIndex((_, a) => f(a)) +): ((as: ReadonlyArray) => Reader>) => traverseReadonlyArrayWithIndex((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(Applicative)`. - * * @since 2.9.0 */ export const sequenceArray: (arr: ReadonlyArray>) => Reader> = @@ -450,6 +519,8 @@ export const sequenceArray: (arr: ReadonlyArray>) => Reader(me: Reader) => ReaderEi /*#__PURE__*/ ET.leftF(R.Functor) -/** - * @category constructors - * @since 2.0.0 - */ -export const ask: () => ReaderEither = () => E.right +// ------------------------------------------------------------------------------------- +// natural transformations +// ------------------------------------------------------------------------------------- /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ -export const asks: (f: (r: R) => A) => ReaderEither = (f) => flow(f, E.right) +export const fromEither: FromEither3['fromEither'] = R.of /** - * @category constructors - * @since 2.0.0 + * @category natural transformations + * @since 2.11.0 */ -export const fromEither: (e: E.Either) => ReaderEither = R.of +export const fromReader: FromReader3['fromReader'] = rightReader // ------------------------------------------------------------------------------------- // destructors @@ -134,7 +145,7 @@ export const match: ( export const matchW: ( onLeft: (e: E) => B, onRight: (a: A) => C -) => (ma: Reader>) => Reader = match as any +) => (ma: Reader>) => Reader = match as any /** * @category destructors @@ -208,6 +219,35 @@ export const toUnion: (fa: ReaderEither) => Reader = // combinators // ------------------------------------------------------------------------------------- +/** + * Changes the value of the local context during the execution of the action `ma` (similar to `Contravariant`'s + * `contramap`). + * + * @category combinators + * @since 2.0.0 + */ +export const local: (f: (r2: R2) => R1) => (ma: ReaderEither) => ReaderEither = + R.local + +/** + * Less strict version of [`asksReaderEither`](#asksreadereither). + * + * @category combinators + * @since 2.11.0 + */ +export const asksReaderEitherW: (f: (r1: R1) => ReaderEither) => ReaderEither = + R.asksReaderW + +/** + * Effectfully accesses the environment. + * + * @category combinators + * @since 2.11.0 + */ +export const asksReaderEither: ( + f: (r: R) => ReaderEither +) => ReaderEither = asksReaderEitherW + /** * @category combinators * @since 2.0.0 @@ -228,6 +268,34 @@ export const orElseW: ( onLeft: (e: E1) => ReaderEither ) => (ma: ReaderEither) => ReaderEither = orElse as any +/** + * @category combinators + * @since 2.11.0 + */ +export const orElseFirst: ( + onLeft: (e: E) => ReaderEither +) => (ma: ReaderEither) => ReaderEither = + /*#__PURE__*/ + ET.orElseFirst(R.Monad) + +/** + * @category combinators + * @since 2.11.0 + */ +export const orElseFirstW: ( + onLeft: (e: E1) => ReaderEither +) => (ma: ReaderEither) => ReaderEither = orElseFirst as any + +/** + * @category combinators + * @since 2.11.0 + */ +export const orLeft: ( + onLeft: (e: E1) => Reader +) => (fa: ReaderEither) => ReaderEither = + /*#__PURE__*/ + ET.orLeft(R.Monad) + /** * @category combinators * @since 2.0.0 @@ -341,15 +409,25 @@ export const chainW: ( f: (a: A) => ReaderEither ) => (ma: ReaderEither) => ReaderEither = chain as any +/** + * Less strict version of [`flatten`](#flatten). + * + * @category combinators + * @since 2.11.0 + */ +export const flattenW: ( + mma: ReaderEither> +) => ReaderEither = + /*#__PURE__*/ + chainW(identity) + /** * Derivable from `Chain`. * * @category combinators * @since 2.0.0 */ -export const flatten: (mma: ReaderEither>) => ReaderEither = - /*#__PURE__*/ - chain(identity) +export const flatten: (mma: ReaderEither>) => ReaderEither = flattenW /** * Identifies an associative operation on a type constructor. It is similar to `Semigroup`, except that it applies to @@ -611,6 +689,85 @@ export const Alt: Alt3 = { alt: _alt } +/** + * @category instances + * @since 2.11.0 + */ +export const FromReader: FromReader3 = { + URI, + fromReader +} + +/** + * Reads the current context. + * + * @category constructors + * @since 2.0.0 + */ +export const ask: () => ReaderEither = + /*#__PURE__*/ + ask_(FromReader) + +/** + * Projects a value from the global context in a `ReaderEither`. + * + * @category constructors + * @since 2.0.0 + */ +export const asks: (f: (r: R) => A) => ReaderEither = + /*#__PURE__*/ + asks_(FromReader) + +/** + * @category combinators + * @since 2.11.0 + */ +export const fromReaderK: , R, B>( + f: (...a: A) => Reader +) => (...a: A) => ReaderEither = + /*#__PURE__*/ + fromReaderK_(FromReader) + +/** + * @category combinators + * @since 2.11.0 + */ +export const chainReaderK: ( + f: (a: A) => Reader +) => (ma: ReaderEither) => ReaderEither = + /*#__PURE__*/ + chainReaderK_(FromReader, Chain) + +/** + * Less strict version of [`chainReaderK`](#chainreaderk). + * + * @category combinators + * @since 2.11.0 + */ +export const chainReaderKW: ( + f: (a: A) => Reader +) => (ma: ReaderEither) => ReaderEither = chainReaderK as any + +/** + * @category combinators + * @since 2.11.0 + */ +export const chainFirstReaderK: ( + f: (a: A) => Reader +) => (ma: ReaderEither) => ReaderEither = + /*#__PURE__*/ + chainFirstReaderK_(FromReader, Chain) + +/** + * Less strict version of [`chainReaderK`](#chainreaderk). + * + * @category combinators + * @since 2.11.0 + */ +export const chainFirstReaderKW: ( + f: (a: A) => Reader +) => (ma: ReaderEither) => ReaderEither = chainFirstReaderK as any + /** * @category instances * @since 2.7.0 @@ -634,10 +791,10 @@ export const FromEither: FromEither3 = { } /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ -export const fromOption: (onNone: Lazy) => (ma: Option) => ReaderEither = +export const fromOption: (onNone: Lazy) => NaturalTransformation13C = /*#__PURE__*/ fromOption_(FromEither) @@ -683,6 +840,7 @@ export const chainEitherKW: ( */ export const fromPredicate: { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => ReaderEither + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => ReaderEither (predicate: Predicate, onFalse: (a: A) => E): (a: A) => ReaderEither } = /*#__PURE__*/ @@ -696,6 +854,9 @@ export const filterOrElse: { (refinement: Refinement, onFalse: (a: A) => E): ( ma: ReaderEither ) => ReaderEither + (predicate: Predicate, onFalse: (a: A) => E): ( + mb: ReaderEither + ) => ReaderEither (predicate: Predicate, onFalse: (a: A) => E): (ma: ReaderEither) => ReaderEither } = /*#__PURE__*/ @@ -711,6 +872,9 @@ export const filterOrElseW: { (refinement: Refinement, onFalse: (a: A) => E2): ( ma: ReaderEither ) => ReaderEither + (predicate: Predicate, onFalse: (a: A) => E2): ( + mb: ReaderEither + ) => ReaderEither (predicate: Predicate, onFalse: (a: A) => E2): ( ma: ReaderEither ) => ReaderEither @@ -735,7 +899,7 @@ export const fromEitherK: , B>( */ export const Do: ReaderEither = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 @@ -782,32 +946,56 @@ export const apSW: ( fa: ReaderEither ) => ReaderEither = apS as any +// ------------------------------------------------------------------------------------- +// sequence T +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export const ApT: ReaderEither = of(_.emptyReadonlyArray) + // ------------------------------------------------------------------------------------- // array utils // ------------------------------------------------------------------------------------- +/** + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. + * + * @since 2.11.0 + */ +export const traverseReadonlyNonEmptyArrayWithIndex = ( + f: (index: number, a: A) => ReaderEither +): ((as: ReadonlyNonEmptyArray) => ReaderEither>) => + flow(R.traverseReadonlyNonEmptyArrayWithIndex(f), R.map(E.traverseReadonlyNonEmptyArrayWithIndex(SK))) + /** * Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndex = ( + f: (index: number, a: A) => ReaderEither +): ((as: ReadonlyArray) => ReaderEither>) => { + const g = traverseReadonlyNonEmptyArrayWithIndex(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + +/** * @since 2.9.0 */ -export const traverseArrayWithIndex = ( +export const traverseArrayWithIndex: ( f: (index: number, a: A) => ReaderEither -): ((as: ReadonlyArray) => ReaderEither>) => - flow(R.traverseArrayWithIndex(f), R.map(E.sequenceArray)) +) => (as: ReadonlyArray) => ReaderEither> = traverseReadonlyArrayWithIndex /** - * Equivalent to `ReadonlyArray#traverse(Applicative)`. - * * @since 2.9.0 */ export const traverseArray = ( f: (a: A) => ReaderEither -): ((as: ReadonlyArray) => ReaderEither>) => traverseArrayWithIndex((_, a) => f(a)) +): ((as: ReadonlyArray) => ReaderEither>) => traverseReadonlyArrayWithIndex((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(Applicative)`. - * * @since 2.9.0 */ export const sequenceArray: ( @@ -820,6 +1008,8 @@ export const sequenceArray: ( // deprecated // ------------------------------------------------------------------------------------- +// tslint:disable: deprecation + /** * Use small, specific instances instead. * @@ -896,13 +1086,3 @@ export function getReaderValidation( throwError } } - -/** - * Use [`local`](./Reader.ts.html#local) instead. - * - * @category combinators - * @since 2.0.0 - * @deprecated - */ -export const local: (f: (r2: R2) => R1) => (ma: ReaderEither) => ReaderEither = - R.local diff --git a/src/ReaderT.ts b/src/ReaderT.ts index d16f89769..2f4c8393a 100644 --- a/src/ReaderT.ts +++ b/src/ReaderT.ts @@ -7,6 +7,14 @@ import { flow, pipe } from './function' import { Functor, Functor1, Functor2, Functor2C, Functor3, Functor3C, Functor4 } from './Functor' import { HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT' import { Monad, Monad1, Monad2, Monad2C, Monad3 } from './Monad' +import { + NaturalTransformation22, + NaturalTransformation12, + NaturalTransformation11, + NaturalTransformation, + NaturalTransformation23R, + NaturalTransformation24S +} from './NaturalTransformation' import { Pointed, Pointed1, Pointed2, Pointed2C, Pointed3, Pointed3C, Pointed4 } from './Pointed' import { Reader } from './Reader' @@ -150,6 +158,34 @@ export function fromReader(F: Pointed): (ma: Reader) => Reader return (ma) => flow(ma, F.of) } +/** + * @category constructors + * @since 2.11.0 + */ +export function fromNaturalTransformation( + nt: NaturalTransformation24S +): (f: (r: R) => Kind2) => Reader> +export function fromNaturalTransformation( + nt: NaturalTransformation23R +): (f: (r: R) => Kind2) => Reader> +export function fromNaturalTransformation( + nt: NaturalTransformation22 +): (f: (r: R) => Kind2) => Reader> +export function fromNaturalTransformation( + nt: NaturalTransformation12 +): (f: (r: R) => Kind) => Reader> +export function fromNaturalTransformation( + nt: NaturalTransformation11 +): (f: (r: R) => Kind) => Reader> +export function fromNaturalTransformation( + nt: NaturalTransformation +): (f: (r: R) => HKT) => Reader> +export function fromNaturalTransformation( + nt: NaturalTransformation +): (f: (r: R) => HKT) => Reader> { + return (f) => flow(f, nt) +} + // ------------------------------------------------------------------------------------- // deprecated // ------------------------------------------------------------------------------------- diff --git a/src/ReaderTask.ts b/src/ReaderTask.ts index 5741b35a1..a0692ecc7 100644 --- a/src/ReaderTask.ts +++ b/src/ReaderTask.ts @@ -11,14 +11,23 @@ import { } from './Apply' import { bind as bind_, Chain2, chainFirst as chainFirst_ } from './Chain' import { chainFirstIOK as chainFirstIOK_, chainIOK as chainIOK_, FromIO2, fromIOK as fromIOK_ } from './FromIO' +import { + ask as ask_, + asks as asks_, + chainFirstReaderK as chainFirstReaderK_, + chainReaderK as chainReaderK_, + FromReader2, + fromReaderK as fromReaderK_ +} from './FromReader' import { chainFirstTaskK as chainFirstTaskK_, chainTaskK as chainTaskK_, FromTask2, fromTaskK as fromTaskK_ } from './FromTask' -import { flow, identity, pipe } from './function' +import { flow, identity, pipe, SK } from './function' import { bindTo as bindTo_, flap as flap_, Functor2 } from './Functor' +import * as _ from './internal' import { Monad2 } from './Monad' import { MonadIO2 } from './MonadIO' import { MonadTask2 } from './MonadTask' @@ -26,6 +35,7 @@ import { Monoid } from './Monoid' import { Pointed2 } from './Pointed' import * as R from './Reader' import * as RT from './ReaderT' +import { ReadonlyNonEmptyArray } from './ReadonlyNonEmptyArray' import { Semigroup } from './Semigroup' import * as T from './Task' @@ -34,7 +44,6 @@ import * as T from './Task' // ------------------------------------------------------------------------------------- import Task = T.Task -import Reader = R.Reader /** * @category model @@ -45,61 +54,74 @@ export interface ReaderTask { } // ------------------------------------------------------------------------------------- -// constructors +// natural transformations // ------------------------------------------------------------------------------------- /** - * @category constructors + * @category natural transformations * @since 2.3.0 */ -export const fromReader: (ma: Reader) => ReaderTask = +export const fromReader: FromReader2['fromReader'] = /*#__PURE__*/ RT.fromReader(T.Pointed) /** - * @category constructors + * @category natural transformations * @since 2.3.0 */ -export const ask = (): ReaderTask => T.of +export const fromTask: FromTask2['fromTask'] = + /*#__PURE__*/ + R.of /** - * @category constructors + * @category natural transformations * @since 2.3.0 */ -export const asks = (f: (r: R) => A): ReaderTask => flow(f, T.of) +export const fromIO: FromIO2['fromIO'] = + /*#__PURE__*/ + flow(T.fromIO, fromTask) + +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- /** - * @category constructors + * Changes the value of the local context during the execution of the action `ma` (similar to `Contravariant`'s + * `contramap`). + * + * @category combinators * @since 2.3.0 */ -export const fromTask: FromTask2['fromTask'] = - /*#__PURE__*/ - R.of +export const local: (f: (r2: R2) => R1) => (ma: ReaderTask) => ReaderTask = R.local /** - * @category constructors - * @since 2.3.0 + * Less strict version of [`asksReaderTask`](#asksreadertask). + * + * @category combinators + * @since 2.11.0 */ -export const fromIO: FromIO2['fromIO'] = - /*#__PURE__*/ - flow(T.fromIO, fromTask) +export const asksReaderTaskW: (f: (r1: R1) => ReaderTask) => ReaderTask = R.asksReaderW + +/** + * Effectfully accesses the environment. + * + * @category combinators + * @since 2.11.0 + */ +export const asksReaderTask: (f: (r: R) => ReaderTask) => ReaderTask = asksReaderTaskW // ------------------------------------------------------------------------------------- -// non-pipeables +// type class members // ------------------------------------------------------------------------------------- -const _map: Monad2['map'] = (fa, f) => pipe(fa, map(f)) -const _apPar: Monad2['ap'] = (fab, fa) => pipe(fab, ap(fa)) -const _apSeq: Monad2['ap'] = (fab, fa) => +const _map: Functor2['map'] = (fa, f) => pipe(fa, map(f)) +const _apPar: Apply2['ap'] = (fab, fa) => pipe(fab, ap(fa)) +const _apSeq: Apply2['ap'] = (fab, fa) => pipe( fab, chain((f) => pipe(fa, map(f))) ) -const _chain: Monad2['chain'] = (ma, f) => pipe(ma, chain(f)) - -// ------------------------------------------------------------------------------------- -// type class members -// ------------------------------------------------------------------------------------- +const _chain: Chain2['chain'] = (ma, f) => pipe(ma, chain(f)) /** * `map` can be used to turn functions `(a: A) => B` into functions `(fa: F) => F` whose argument and return types @@ -160,15 +182,23 @@ export const chainW: ( f: (a: A) => ReaderTask ) => (ma: ReaderTask) => ReaderTask = chain as any +/** + * Less strict version of [`flatten`](#flatten). + * + * @category combinators + * @since 2.11.0 + */ +export const flattenW: (mma: ReaderTask>) => ReaderTask = + /*#__PURE__*/ + chainW(identity) + /** * Derivable from `Chain`. * * @category combinators * @since 2.3.0 */ -export const flatten: (mma: ReaderTask>) => ReaderTask = - /*#__PURE__*/ - chain(identity) +export const flatten: (mma: ReaderTask>) => ReaderTask = flattenW // ------------------------------------------------------------------------------------- // instances @@ -349,6 +379,18 @@ export const chainFirst = /*#__PURE__*/ chainFirst_(Chain) +/** + * Less strict version of [`chainFirst`](#chainfirst). + * + * Derivable from `Chain`. + * + * @category combinators + * @since 2.11.0 + */ +export const chainFirstW: ( + f: (a: A) => ReaderTask +) => (ma: ReaderTask) => ReaderTask = chainFirst as any + /** * @category instances * @since 2.10.0 @@ -382,6 +424,79 @@ export const chainFirstIOK = /*#__PURE__*/ chainFirstIOK_(FromIO, Chain) +/** + * @category instances + * @since 2.11.0 + */ +export const FromReader: FromReader2 = { + URI, + fromReader +} + +/** + * Reads the current context. + * + * @category constructors + * @since 2.3.0 + */ +export const ask = + /*#__PURE__*/ + ask_(FromReader) + +/** + * Projects a value from the global context in a `ReaderTask`. + * + * @category constructors + * @since 2.3.0 + */ +export const asks = + /*#__PURE__*/ + asks_(FromReader) + +/** + * @category combinators + * @since 2.11.0 + */ +export const fromReaderK = + /*#__PURE__*/ + fromReaderK_(FromReader) + +/** + * @category combinators + * @since 2.11.0 + */ +export const chainReaderK = + /*#__PURE__*/ + chainReaderK_(FromReader, Chain) + +/** + * Less strict version of [`chainReaderK`](#chainreaderk). + * + * @category combinators + * @since 2.11.0 + */ +export const chainReaderKW: ( + f: (a: A) => R.Reader +) => (ma: ReaderTask) => ReaderTask = chainReaderK as any + +/** + * @category combinators + * @since 2.11.0 + */ +export const chainFirstReaderK = + /*#__PURE__*/ + chainFirstReaderK_(FromReader, Chain) + +/** + * Less strict version of [`chainFirstReaderK`](#chainfirstreaderk). + * + * @category combinators + * @since 2.11.0 + */ +export const chainFirstReaderKW: ( + f: (a: A) => R.Reader +) => (ma: ReaderTask) => ReaderTask = chainFirstReaderK as any + /** * @category instances * @since 2.10.0 @@ -425,7 +540,7 @@ export const chainFirstTaskK = */ export const Do: ReaderTask = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 @@ -472,32 +587,78 @@ export const apSW: ( fa: ReaderTask ) => ReaderTask = apS as any +// ------------------------------------------------------------------------------------- +// sequence T +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export const ApT: ReaderTask = of(_.emptyReadonlyArray) + // ------------------------------------------------------------------------------------- // array utils // ------------------------------------------------------------------------------------- /** - * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. * - * @since 2.9.0 + * @since 2.11.0 */ -export const traverseArrayWithIndex = ( +export const traverseReadonlyNonEmptyArrayWithIndex = ( f: (index: number, a: A) => ReaderTask -): ((as: ReadonlyArray) => ReaderTask>) => - flow(R.traverseArrayWithIndex(f), R.map(T.sequenceArray)) +): ((as: ReadonlyNonEmptyArray) => ReaderTask>) => + flow(R.traverseReadonlyNonEmptyArrayWithIndex(f), R.map(T.traverseReadonlyNonEmptyArrayWithIndex(SK))) /** - * Equivalent to `ReadonlyArray#traverse(ApplicativePar)`. + * Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndex = ( + f: (index: number, a: A) => ReaderTask +): ((as: ReadonlyArray) => ReaderTask>) => { + const g = traverseReadonlyNonEmptyArrayWithIndex(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + +/** + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativeSeq)`. + * + * @since 2.11.0 + */ +export const traverseReadonlyNonEmptyArrayWithIndexSeq = ( + f: (index: number, a: A) => ReaderTask +): ((as: ReadonlyNonEmptyArray) => ReaderTask>) => + flow(R.traverseReadonlyNonEmptyArrayWithIndex(f), R.map(T.traverseReadonlyNonEmptyArrayWithIndexSeq(SK))) + +/** + * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. + * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndexSeq = ( + f: (index: number, a: A) => ReaderTask +): ((as: ReadonlyArray) => ReaderTask>) => { + const g = traverseReadonlyNonEmptyArrayWithIndexSeq(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + +/** + * @since 2.9.0 + */ +export const traverseArrayWithIndex: ( + f: (index: number, a: A) => ReaderTask +) => (as: ReadonlyArray) => ReaderTask> = traverseReadonlyArrayWithIndex + +/** * @since 2.9.0 */ export const traverseArray = ( f: (a: A) => ReaderTask -): ((as: ReadonlyArray) => ReaderTask>) => traverseArrayWithIndex((_, a) => f(a)) +): ((as: ReadonlyArray) => ReaderTask>) => traverseReadonlyArrayWithIndex((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(ApplicativePar)`. - * * @since 2.9.0 */ export const sequenceArray: (arr: ReadonlyArray>) => ReaderTask> = @@ -505,28 +666,24 @@ export const sequenceArray: (arr: ReadonlyArray>) => Read traverseArray(identity) /** - * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. - * * @since 2.10.0 */ -export const traverseSeqArrayWithIndex = ( +export const traverseSeqArrayWithIndex: ( f: (index: number, a: A) => ReaderTask -): ((as: ReadonlyArray) => ReaderTask>) => - flow(R.traverseArrayWithIndex(f), R.map(T.sequenceSeqArray)) +) => (as: ReadonlyArray) => ReaderTask> = traverseReadonlyArrayWithIndexSeq /** - * Equivalent to `ReadonlyArray#traverse(ApplicativeSeq)`. - * * @since 2.10.0 */ export const traverseSeqArray = ( f: (a: A) => ReaderTask -): ((as: ReadonlyArray) => ReaderTask>) => traverseSeqArrayWithIndex((_, a) => f(a)) +): ((as: ReadonlyArray) => ReaderTask>) => traverseReadonlyArrayWithIndexSeq((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(ApplicativeSeq)`. + * Use `traverseReadonlyArrayWithIndexSeq` instead. * * @since 2.10.0 + * @deprecated */ export const sequenceSeqArray: (arr: ReadonlyArray>) => ReaderTask> = /*#__PURE__*/ @@ -603,12 +760,3 @@ export const getMonoid: (M: Monoid) => Monoid> = export function run(ma: ReaderTask, r: R): Promise { return ma(r)() } - -/** - * Use [`local`](./Reader.ts.html#local) instead. - * - * @category combinators - * @since 2.3.0 - * @deprecated - */ -export const local: (f: (r2: R2) => R1) => (ma: ReaderTask) => ReaderTask = R.local diff --git a/src/ReaderTaskEither.ts b/src/ReaderTaskEither.ts index 8bae66ba1..9e786425f 100644 --- a/src/ReaderTaskEither.ts +++ b/src/ReaderTaskEither.ts @@ -35,26 +35,39 @@ import { fromPredicate as fromPredicate_ } from './FromEither' import { chainFirstIOK as chainFirstIOK_, chainIOK as chainIOK_, FromIO3, fromIOK as fromIOK_ } from './FromIO' +import { + ask as ask_, + asks as asks_, + chainFirstReaderK as chainFirstReaderK_, + chainReaderK as chainReaderK_, + FromReader3, + fromReaderK as fromReaderK_ +} from './FromReader' import { chainFirstTaskK as chainFirstTaskK_, chainTaskK as chainTaskK_, FromTask3, fromTaskK as fromTaskK_ } from './FromTask' -import { flow, identity, Lazy, pipe, Predicate, Refinement } from './function' +import { flow, identity, Lazy, pipe, SK } from './function' import { bindTo as bindTo_, flap as flap_, Functor3 } from './Functor' +import * as _ from './internal' import { IO } from './IO' -import { IOEither } from './IOEither' +import { IOEither, URI as IEURI } from './IOEither' import { Monad3, Monad3C } from './Monad' import { MonadIO3 } from './MonadIO' import { MonadTask3, MonadTask3C } from './MonadTask' import { MonadThrow3, MonadThrow3C } from './MonadThrow' import { Monoid } from './Monoid' -import { Option } from './Option' +import { NaturalTransformation13C, NaturalTransformation23, NaturalTransformation33 } from './NaturalTransformation' +import { URI as OURI } from './Option' import { Pointed3 } from './Pointed' +import { Predicate } from './Predicate' import * as R from './Reader' -import { ReaderEither } from './ReaderEither' +import { ReaderEither, URI as REURI } from './ReaderEither' import * as RT from './ReaderTask' +import { ReadonlyNonEmptyArray } from './ReadonlyNonEmptyArray' +import { Refinement } from './Refinement' import { Semigroup } from './Semigroup' import * as T from './Task' import * as TE from './TaskEither' @@ -82,10 +95,10 @@ export interface ReaderTaskEither { // ------------------------------------------------------------------------------------- /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ -export const fromTaskEither: (ma: TaskEither) => ReaderTaskEither = +export const fromTaskEither: NaturalTransformation23 = /*#__PURE__*/ R.of @@ -155,63 +168,59 @@ export const leftReaderTask: (me: ReaderTask) => * @category constructors * @since 2.0.0 */ -export const fromIOEither: (ma: IOEither) => ReaderTaskEither = +export const rightIO: (ma: IO) => ReaderTaskEither = /*#__PURE__*/ - flow(TE.fromIOEither, fromTaskEither) - -/** - * @category constructors - * @since 2.0.0 - */ -export const fromReaderEither = (ma: ReaderEither): ReaderTaskEither => - flow(ma, TE.fromEither) + flow(TE.rightIO, fromTaskEither) /** * @category constructors * @since 2.0.0 */ -export const rightIO: (ma: IO) => ReaderTaskEither = +export const leftIO: (me: IO) => ReaderTaskEither = /*#__PURE__*/ - flow(TE.rightIO, fromTaskEither) + flow(TE.leftIO, fromTaskEither) + +// ------------------------------------------------------------------------------------- +// natural transformations +// ------------------------------------------------------------------------------------- /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ -export const fromIO: FromIO3['fromIO'] = rightIO +export const fromEither: FromEither3['fromEither'] = RT.of /** - * @category constructors - * @since 2.0.0 + * @category natural transformations + * @since 2.11.0 */ -export const fromTask: FromTask3['fromTask'] = rightTask +export const fromReader: FromReader3['fromReader'] = rightReader /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ -export const leftIO: (me: IO) => ReaderTaskEither = - /*#__PURE__*/ - flow(TE.leftIO, fromTaskEither) +export const fromIO: FromIO3['fromIO'] = rightIO /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ -export const ask: () => ReaderTaskEither = () => TE.right +export const fromTask: FromTask3['fromTask'] = rightTask /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ -export const asks: (f: (r: R) => A) => ReaderTaskEither = (f) => - flow(TE.right, TE.map(f)) +export const fromIOEither: NaturalTransformation23 = + /*#__PURE__*/ + flow(TE.fromIOEither, fromTaskEither) /** * @category constructors * @since 2.0.0 */ -export const fromEither: (e: E.Either) => ReaderTaskEither = RT.of +export const fromReaderEither: NaturalTransformation33 = (ma) => flow(ma, TE.fromEither) // ------------------------------------------------------------------------------------- // destructors @@ -313,6 +322,37 @@ export const toUnion: (fa: ReaderTaskEither) => ReaderTask( + f: (r2: R2) => R1 +) => (ma: ReaderTaskEither) => ReaderTaskEither = R.local + +/** + * Less strict version of [`asksReaderTaskEither`](#asksreadertaskeither). + * + * @category combinators + * @since 2.11.0 + */ +export const asksReaderTaskEitherW: ( + f: (r1: R1) => ReaderTaskEither +) => ReaderTaskEither = R.asksReaderW + +/** + * Effectfully accesses the environment. + * + * @category combinators + * @since 2.11.0 + */ +export const asksReaderTaskEither: ( + f: (r: R) => ReaderTaskEither +) => ReaderTaskEither = asksReaderTaskEitherW + /** * @category combinators * @since 2.0.0 @@ -333,6 +373,34 @@ export const orElseW: ( onLeft: (e: E1) => ReaderTaskEither ) => (ma: ReaderTaskEither) => ReaderTaskEither = orElse as any +/** + * @category combinators + * @since 2.11.0 + */ +export const orElseFirst: ( + onLeft: (e: E) => ReaderTaskEither +) => (ma: ReaderTaskEither) => ReaderTaskEither = + /*#__PURE__*/ + ET.orElseFirst(RT.Monad) + +/** + * @category combinators + * @since 2.11.0 + */ +export const orElseFirstW: ( + onLeft: (e: E1) => ReaderTaskEither +) => (ma: ReaderTaskEither) => ReaderTaskEither = orElseFirst as any + +/** + * @category combinators + * @since 2.11.0 + */ +export const orLeft: ( + onLeft: (e: E1) => ReaderTask +) => (fa: ReaderTaskEither) => ReaderTaskEither = + /*#__PURE__*/ + ET.orLeft(RT.Monad) + /** * @category combinators * @since 2.0.0 @@ -393,19 +461,83 @@ export const chainTaskEitherK: ( f: (a: A) => TaskEither ) => (ma: ReaderTaskEither) => ReaderTaskEither = chainTaskEitherKW +/** + * Less strict version of [`chainFirstTaskEitherK`](#chainfirsttaskeitherk). + * + * @category combinators + * @since 2.11.0 + */ +export const chainFirstTaskEitherKW: ( + f: (a: A) => TaskEither +) => (ma: ReaderTaskEither) => ReaderTaskEither = (f) => chainFirstW(fromTaskEitherK(f)) + +/** + * @category combinators + * @since 2.11.0 + */ +export const chainFirstTaskEitherK: ( + f: (a: A) => TaskEither +) => (ma: ReaderTaskEither) => ReaderTaskEither = chainFirstTaskEitherKW + +/** + * @category combinators + * @since 2.11.0 + */ +export const fromReaderEitherK = , B>( + f: (...a: A) => ReaderEither +): ((...a: A) => ReaderTaskEither) => flow(f, fromReaderEither) + +/** + * Less strict version of [`chainReaderEitherK`](#chainreadereitherk). + * + * @category combinators + * @since 2.11.0 + */ +export const chainReaderEitherKW: ( + f: (a: A) => ReaderEither +) => (ma: ReaderTaskEither) => ReaderTaskEither = (f) => + chainW(fromReaderEitherK(f)) + +/** + * @category combinators + * @since 2.11.0 + */ +export const chainReaderEitherK: ( + f: (a: A) => ReaderEither +) => (ma: ReaderTaskEither) => ReaderTaskEither = chainReaderEitherKW + +/** + * Less strict version of [`chainFirstReaderEitherK`](#chainfirstreadereitherk). + * + * @category combinators + * @since 2.11.0 + */ +export const chainFirstReaderEitherKW: ( + f: (a: A) => ReaderEither +) => (ma: ReaderTaskEither) => ReaderTaskEither = (f) => + chainFirstW(fromReaderEitherK(f)) + +/** + * @category combinators + * @since 2.11.0 + */ +export const chainFirstReaderEitherK: ( + f: (a: A) => ReaderEither +) => (ma: ReaderTaskEither) => ReaderTaskEither = chainFirstReaderEitherKW + // ------------------------------------------------------------------------------------- // non-pipeables // ------------------------------------------------------------------------------------- -const _map: Monad3['map'] = (fa, f) => pipe(fa, map(f)) -const _apPar: Monad3['ap'] = (fab, fa) => pipe(fab, ap(fa)) -const _apSeq: Monad3['ap'] = (fab, fa) => +const _map: Functor3['map'] = (fa, f) => pipe(fa, map(f)) +const _apPar: Apply3['ap'] = (fab, fa) => pipe(fab, ap(fa)) +const _apSeq: Apply3['ap'] = (fab, fa) => pipe( fab, chain((f) => pipe(fa, map(f))) ) /* istanbul ignore next */ -const _chain: Monad3['chain'] = (ma, f) => pipe(ma, chain(f)) +const _chain: Chain3['chain'] = (ma, f) => pipe(ma, chain(f)) /* istanbul ignore next */ const _alt: Alt3['alt'] = (fa, that) => pipe(fa, alt(that)) /* istanbul ignore next */ @@ -501,15 +633,27 @@ export const chainW: ( f: (a: A) => ReaderTaskEither ) => (ma: ReaderTaskEither) => ReaderTaskEither = chain as any +/** + * Less strict version of [`flatten`](#flatten). + * + * @category combinators + * @since 2.11.0 + */ +export const flattenW: ( + mma: ReaderTaskEither> +) => ReaderTaskEither = + /*#__PURE__*/ + chainW(identity) + /** * Derivable from `Chain`. * * @category combinators * @since 2.0.0 */ -export const flatten: (mma: ReaderTaskEither>) => ReaderTaskEither = - /*#__PURE__*/ - chain(identity) +export const flatten: ( + mma: ReaderTaskEither> +) => ReaderTaskEither = flattenW /** * Identifies an associative operation on a type constructor. It is similar to `Semigroup`, except that it applies to @@ -834,6 +978,131 @@ export const Alt: Alt3 = { alt: _alt } +/** + * @category instances + * @since 2.11.0 + */ +export const FromReader: FromReader3 = { + URI, + fromReader +} + +/** + * Reads the current context. + * + * @category constructors + * @since 2.0.0 + */ +export const ask: () => ReaderTaskEither = + /*#__PURE__*/ + ask_(FromReader) + +/** + * Projects a value from the global context in a `ReaderEither`. + * + * @category constructors + * @since 2.0.0 + */ +export const asks: (f: (r: R) => A) => ReaderTaskEither = + /*#__PURE__*/ + asks_(FromReader) + +/** + * @category combinators + * @since 2.11.0 + */ +export const fromReaderK: , R, B>( + f: (...a: A) => Reader +) => (...a: A) => ReaderTaskEither = + /*#__PURE__*/ + fromReaderK_(FromReader) + +/** + * @category combinators + * @since 2.11.0 + */ +export const chainReaderK: ( + f: (a: A) => Reader +) => (ma: ReaderTaskEither) => ReaderTaskEither = + /*#__PURE__*/ + chainReaderK_(FromReader, Chain) + +/** + * Less strict version of [`chainReaderK`](#chainreaderk). + * + * @category combinators + * @since 2.11.0 + */ +export const chainReaderKW: ( + f: (a: A) => R.Reader +) => (ma: ReaderTaskEither) => ReaderTaskEither = chainReaderK as any + +/** + * @category combinators + * @since 2.11.0 + */ +export const chainFirstReaderK: ( + f: (a: A) => R.Reader +) => (ma: ReaderTaskEither) => ReaderTaskEither = + /*#__PURE__*/ + chainFirstReaderK_(FromReader, Chain) + +/** + * Less strict version of [`chainFirstReaderK`](#chainfirstreaderk). + * + * @category combinators + * @since 2.11.0 + */ +export const chainFirstReaderKW: ( + f: (a: A) => R.Reader +) => (ma: ReaderTaskEither) => ReaderTaskEither = chainFirstReaderK as any + +/** + * @category combinators + * @since 2.11.0 + */ +export const fromReaderTaskK = , R, B>( + f: (...a: A) => ReaderTask +): ((...a: A) => ReaderTaskEither) => (...a) => rightReaderTask(f(...a)) + +/** + * Less strict version of [`chainReaderTaskK`](#chainreadertaskk). + * + * @category combinators + * @since 2.11.0 + */ +export const chainReaderTaskKW: ( + f: (a: A) => RT.ReaderTask +) => (ma: ReaderTaskEither) => ReaderTaskEither = (f) => + chainW(fromReaderTaskK(f)) + +/** + * @category combinators + * @since 2.11.0 + */ +export const chainReaderTaskK: ( + f: (a: A) => RT.ReaderTask +) => (ma: ReaderTaskEither) => ReaderTaskEither = chainReaderTaskKW + +/** + * Less strict version of [`chainFirstReaderTaskK`](#chainfirstreadertaskk). + * + * @category combinators + * @since 2.11.0 + */ +export const chainFirstReaderTaskKW: ( + f: (a: A) => RT.ReaderTask +) => (ma: ReaderTaskEither) => ReaderTaskEither = (f) => + chainFirstW(fromReaderTaskK(f)) + +/** + * @category combinators + * @since 2.11.0 + */ +export const chainFirstReaderTaskK: ( + f: (a: A) => RT.ReaderTask +) => (ma: ReaderTaskEither) => ReaderTaskEither = chainFirstReaderTaskKW + /** * @category instances * @since 2.10.0 @@ -844,10 +1113,10 @@ export const FromEither: FromEither3 = { } /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ -export const fromOption: (onNone: Lazy) => (ma: Option) => ReaderTaskEither = +export const fromOption: (onNone: Lazy) => NaturalTransformation13C = /*#__PURE__*/ fromOption_(FromEither) @@ -893,6 +1162,7 @@ export const chainEitherKW: ( */ export const fromPredicate: { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => ReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => ReaderTaskEither (predicate: Predicate, onFalse: (a: A) => E): (a: A) => ReaderTaskEither } = /*#__PURE__*/ @@ -906,6 +1176,9 @@ export const filterOrElse: { (refinement: Refinement, onFalse: (a: A) => E): ( ma: ReaderTaskEither ) => ReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E): ( + mb: ReaderTaskEither + ) => ReaderTaskEither (predicate: Predicate, onFalse: (a: A) => E): (ma: ReaderTaskEither) => ReaderTaskEither } = /*#__PURE__*/ @@ -921,6 +1194,9 @@ export const filterOrElseW: { (refinement: Refinement, onFalse: (a: A) => E2): ( ma: ReaderTaskEither ) => ReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E2): ( + mb: ReaderTaskEither + ) => ReaderTaskEither (predicate: Predicate, onFalse: (a: A) => E2): ( ma: ReaderTaskEither ) => ReaderTaskEither @@ -1037,7 +1313,7 @@ export function bracket( */ export const Do: ReaderTaskEither = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 @@ -1084,32 +1360,79 @@ export const apSW: ( fa: ReaderTaskEither ) => ReaderTaskEither = apS as any +// ------------------------------------------------------------------------------------- +// sequence T +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export const ApT: ReaderTaskEither = of(_.emptyReadonlyArray) + // ------------------------------------------------------------------------------------- // array utils // ------------------------------------------------------------------------------------- +/** + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativePar)`. + * + * @since 2.11.0 + */ +export const traverseReadonlyNonEmptyArrayWithIndex = ( + f: (index: number, a: A) => ReaderTaskEither +): ((as: ReadonlyNonEmptyArray) => ReaderTaskEither>) => + flow(R.traverseReadonlyNonEmptyArrayWithIndex(f), R.map(TE.traverseReadonlyNonEmptyArrayWithIndex(SK))) + /** * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. * - * @since 2.9.0 + * @since 2.11.0 */ -export const traverseArrayWithIndex = ( +export const traverseReadonlyArrayWithIndex = ( f: (index: number, a: A) => ReaderTaskEither -): ((as: ReadonlyArray) => ReaderTaskEither>) => - flow(R.traverseArrayWithIndex(f), R.map(TE.sequenceArray)) +): ((as: ReadonlyArray) => ReaderTaskEither>) => { + const g = traverseReadonlyNonEmptyArrayWithIndex(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} /** - * Equivalent to `ReadonlyArray#traverse(ApplicativePar)`. + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativeSeq)`. * + * @since 2.11.0 + */ +export const traverseReadonlyNonEmptyArrayWithIndexSeq = ( + f: (index: number, a: A) => ReaderTaskEither +): ((as: ReadonlyNonEmptyArray) => ReaderTaskEither>) => + flow(R.traverseReadonlyNonEmptyArrayWithIndex(f), R.map(TE.traverseReadonlyNonEmptyArrayWithIndexSeq(SK))) + +/** + * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. + * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndexSeq = ( + f: (index: number, a: A) => ReaderTaskEither +): ((as: ReadonlyArray) => ReaderTaskEither>) => { + const g = traverseReadonlyNonEmptyArrayWithIndexSeq(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + +/** + * @since 2.9.0 + */ +export const traverseArrayWithIndex: ( + f: (index: number, a: A) => ReaderTaskEither +) => (as: ReadonlyArray) => ReaderTaskEither> = traverseReadonlyArrayWithIndex + +/** * @since 2.9.0 */ export const traverseArray = ( f: (a: A) => ReaderTaskEither -): ((as: ReadonlyArray) => ReaderTaskEither>) => traverseArrayWithIndex((_, a) => f(a)) +): ((as: ReadonlyArray) => ReaderTaskEither>) => + traverseReadonlyArrayWithIndex((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(ApplicativePar)`. - * * @since 2.9.0 */ export const sequenceArray: ( @@ -1119,27 +1442,21 @@ export const sequenceArray: ( traverseArray(identity) /** - * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. - * * @since 2.9.0 */ -export const traverseSeqArrayWithIndex = ( +export const traverseSeqArrayWithIndex: ( f: (index: number, a: A) => ReaderTaskEither -): ((as: ReadonlyArray) => ReaderTaskEither>) => - flow(R.traverseArrayWithIndex(f), R.map(TE.sequenceSeqArray)) +) => (as: ReadonlyArray) => ReaderTaskEither> = traverseReadonlyArrayWithIndexSeq /** - * Equivalent to `ReadonlyArray#traverse(ApplicativeSeq)`. - * * @since 2.9.0 */ export const traverseSeqArray = ( f: (a: A) => ReaderTaskEither -): ((as: ReadonlyArray) => ReaderTaskEither>) => traverseSeqArrayWithIndex((_, a) => f(a)) +): ((as: ReadonlyArray) => ReaderTaskEither>) => + traverseReadonlyArrayWithIndexSeq((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(ApplicativeSeq)`. - * * @since 2.9.0 */ export const sequenceSeqArray: ( @@ -1268,14 +1585,3 @@ export function getReaderTaskValidation( export function run(ma: ReaderTaskEither, r: R): Promise> { return ma(r)() } - -/** - * Use [`local`](./Reader.ts.html#local) instead. - * - * @category combinators - * @since 2.0.0 - * @deprecated - */ -export const local: ( - f: (r2: R2) => R1 -) => (ma: ReaderTaskEither) => ReaderTaskEither = R.local diff --git a/src/ReadonlyArray.ts b/src/ReadonlyArray.ts index 335a4377b..d6e30fbfa 100644 --- a/src/ReadonlyArray.ts +++ b/src/ReadonlyArray.ts @@ -6,6 +6,7 @@ import { Alternative1 } from './Alternative' import { Applicative as ApplicativeHKT, Applicative1 } from './Applicative' import { apFirst as apFirst_, Apply1, apS as apS_, apSecond as apSecond_ } from './Apply' import { bind as bind_, Chain1, chainFirst as chainFirst_ } from './Chain' +import { ChainRec1 } from './ChainRec' import { Compactable1 } from './Compactable' import { Either } from './Either' import { Eq, fromEquals } from './Eq' @@ -14,29 +15,67 @@ import { Filterable1 } from './Filterable' import { FilterableWithIndex1, PredicateWithIndex, RefinementWithIndex } from './FilterableWithIndex' import { Foldable1 } from './Foldable' import { FoldableWithIndex1 } from './FoldableWithIndex' -import { identity, Lazy, pipe, Predicate, Refinement } from './function' +import { FromEither1, fromEitherK as fromEitherK_ } from './FromEither' +import { identity, Lazy, pipe } from './function' import { bindTo as bindTo_, flap as flap_, Functor1 } from './Functor' import { FunctorWithIndex1 } from './FunctorWithIndex' import { HKT } from './HKT' +import * as _ from './internal' +import { Magma } from './Magma' import { Monad1 } from './Monad' import { Monoid } from './Monoid' +import { NaturalTransformation11 } from './NaturalTransformation' import { NonEmptyArray } from './NonEmptyArray' import * as N from './number' -import * as O from './Option' +import { Option, URI as OURI } from './Option' import { fromCompare, Ord } from './Ord' import { Pointed1 } from './Pointed' +import { Predicate } from './Predicate' import * as RNEA from './ReadonlyNonEmptyArray' +import { Refinement } from './Refinement' import { Semigroup } from './Semigroup' import { Separated, separated } from './Separated' import { Show } from './Show' import { PipeableTraverse1, Traversable1 } from './Traversable' import { PipeableTraverseWithIndex1, TraversableWithIndex1 } from './TraversableWithIndex' import { Unfoldable1 } from './Unfoldable' -import { PipeableWilt1, PipeableWither1, Witherable1 } from './Witherable' +import { + filterE as filterE_, + PipeableWilt1, + PipeableWither1, + wiltDefault, + Witherable1, + witherDefault +} from './Witherable' +import { Zero1, guard as guard_ } from './Zero' -import Option = O.Option import ReadonlyNonEmptyArray = RNEA.ReadonlyNonEmptyArray +// ------------------------------------------------------------------------------------- +// refinements +// ------------------------------------------------------------------------------------- + +/** + * Test whether a `ReadonlyArray` is empty. + * + * @example + * import { isEmpty } from 'fp-ts/ReadonlyArray' + * + * assert.strictEqual(isEmpty([]), true) + * + * @category refinements + * @since 2.5.0 + */ +export const isEmpty = (as: ReadonlyArray): as is readonly [] => as.length === 0 + +/** + * Test whether a `ReadonlyArray` is non empty. + * + * @category refinements + * @since 2.5.0 + */ +export const isNonEmpty: (as: ReadonlyArray) => as is ReadonlyNonEmptyArray = RNEA.isNonEmpty + // ------------------------------------------------------------------------------------- // constructors // ------------------------------------------------------------------------------------- @@ -55,6 +94,14 @@ import ReadonlyNonEmptyArray = RNEA.ReadonlyNonEmptyArray */ export const prepend = RNEA.prepend +/** + * Less strict version of [`prepend`](#prepend). + * + * @category constructors + * @since 2.11.0 + */ +export const prependW = RNEA.prependW + /** * Append an element to the end of a `ReadonlyArray`, creating a new `ReadonlyNonEmptyArray`. * @@ -69,6 +116,14 @@ export const prepend = RNEA.prepend */ export const append = RNEA.append +/** + * Less strict version of [`append`](#append). + * + * @category constructors + * @since 2.11.0 + */ +export const appendW = RNEA.appendW + /** * Return a `ReadonlyArray` of length `n` with element `i` initialized with `f(i)`. * @@ -83,21 +138,7 @@ export const append = RNEA.append * @category constructors * @since 2.5.0 */ -export const makeBy = (n: number, f: (i: number) => A): ReadonlyArray => (n <= 0 ? empty : RNEA.makeBy(n, f)) - -/** - * Create a `ReadonlyArray` containing a range of integers, including both endpoints. - * - * @example - * import { range } from 'fp-ts/ReadonlyArray' - * - * assert.deepStrictEqual(range(1, 5), [1, 2, 3, 4, 5]) - * - * @category constructors - * @since 2.5.0 - */ -export const range = (start: number, end: number): ReadonlyArray => - start <= end ? makeBy(end - start + 1, (i) => start + i) : [start] +export const makeBy = (n: number, f: (i: number) => A): ReadonlyArray => (n <= 0 ? empty : RNEA.makeBy(f)(n)) /** * Create a `ReadonlyArray` containing a value repeated the specified number of times. @@ -114,12 +155,70 @@ export const range = (start: number, end: number): ReadonlyArray => */ export const replicate = (n: number, a: A): ReadonlyArray => makeBy(n, () => a) +/** + * @category constructors + * @since 2.11.0 + */ +export function fromPredicate(refinement: Refinement): (a: A) => ReadonlyArray +export function fromPredicate(predicate: Predicate): (b: B) => ReadonlyArray +export function fromPredicate(predicate: Predicate): (a: A) => ReadonlyArray +export function fromPredicate(predicate: Predicate): (a: A) => ReadonlyArray { + return (a) => (predicate(a) ? [a] : empty) +} + +// ------------------------------------------------------------------------------------- +// natural transformations +// ------------------------------------------------------------------------------------- + +/** + * @category natural transformations + * @since 2.11.0 + */ +export const fromOption: NaturalTransformation11 = (ma) => (_.isNone(ma) ? empty : [ma.value]) + +/** + * Transforms an `Either` to a `ReadonlyArray`. + * + * @category natural transformations + * @since 2.11.0 + */ +export const fromEither: FromEither1['fromEither'] = (e) => (_.isLeft(e) ? empty : [e.right]) + // ------------------------------------------------------------------------------------- // destructors // ------------------------------------------------------------------------------------- /** - * Break an array into its first element and remaining elements. + * Less strict version of [`match`](#match). + * + * @category destructors + * @since 2.11.0 + */ +export const matchW = (onEmpty: Lazy, onNonEmpty: (as: ReadonlyNonEmptyArray) => C) => ( + as: ReadonlyArray +): B | C => (isNonEmpty(as) ? onNonEmpty(as) : onEmpty()) + +/** + * @category destructors + * @since 2.11.0 + */ +export const match: ( + onEmpty: Lazy, + onNonEmpty: (as: ReadonlyNonEmptyArray) => B +) => (as: ReadonlyArray) => B = matchW + +/** + * Less strict version of [`matchLeft`](#matchleft). + * + * @category destructors + * @since 2.11.0 + */ +export const matchLeftW = (onEmpty: Lazy, onNonEmpty: (head: A, tail: ReadonlyArray) => C) => ( + as: ReadonlyArray +): B | C => (isNonEmpty(as) ? onNonEmpty(RNEA.head(as), RNEA.tail(as)) : onEmpty()) + +/** + * Break a `ReadonlyArray` into its first element and remaining elements. * * @example * import { matchLeft } from 'fp-ts/ReadonlyArray' @@ -130,9 +229,10 @@ export const replicate = (n: number, a: A): ReadonlyArray => makeBy(n, () * @category destructors * @since 2.10.0 */ -export const matchLeft = (onEmpty: Lazy, onNonEmpty: (head: A, tail: ReadonlyArray) => B) => ( - as: ReadonlyArray -): B => (isNonEmpty(as) ? onNonEmpty(RNEA.head(as), RNEA.tail(as)) : onEmpty()) +export const matchLeft: ( + onEmpty: Lazy, + onNonEmpty: (head: A, tail: ReadonlyArray) => B +) => (as: ReadonlyArray) => B = matchLeftW /** * Alias of [`matchLeft`](#matchleft). @@ -146,14 +246,25 @@ export const foldLeft: ( ) => (as: ReadonlyArray) => B = matchLeft /** - * Break an array into its initial elements and the last element. + * Less strict version of [`matchRight`](#matchright). * * @category destructors - * @since 2.10.0 + * @since 2.11.0 */ -export const matchRight = (onEmpty: Lazy, onNonEmpty: (init: ReadonlyArray, last: A) => B) => ( +export const matchRightW = (onEmpty: Lazy, onNonEmpty: (init: ReadonlyArray, last: A) => C) => ( as: ReadonlyArray -): B => (isNonEmpty(as) ? onNonEmpty(RNEA.init(as), RNEA.last(as)) : onEmpty()) +): B | C => (isNonEmpty(as) ? onNonEmpty(RNEA.init(as), RNEA.last(as)) : onEmpty()) + +/** + * Break a `ReadonlyArray` into its initial elements and the last element. + * + * @category destructors + * @since 2.10.0 + */ +export const matchRight: ( + onEmpty: Lazy, + onNonEmpty: (init: ReadonlyArray, last: A) => B +) => (as: ReadonlyArray) => B = matchRightW /** * Alias of [`matchRight`](#matchright). @@ -229,26 +340,6 @@ export const scanRight = (b: B, f: (a: A, b: B) => B) => (as: ReadonlyArra return out } -/** - * Test whether a `ReadonlyArray` is empty. - * - * @example - * import { isEmpty } from 'fp-ts/ReadonlyArray' - * - * assert.strictEqual(isEmpty([]), true) - * - * @since 2.5.0 - */ -export const isEmpty = (as: ReadonlyArray): boolean => as.length === 0 - -/** - * Test whether a `ReadonlyArray` is non empty. - * - * @category guards - * @since 2.5.0 - */ -export const isNonEmpty: (as: ReadonlyArray) => as is ReadonlyNonEmptyArray = RNEA.isNonEmpty - /** * Calculate the number of elements in a `ReadonlyArray`. * @@ -280,7 +371,7 @@ export const isOutOfBound: (i: number, as: ReadonlyArray) => boolean = RNE export function lookup(i: number): (as: ReadonlyArray) => Option export function lookup(i: number, as: ReadonlyArray): Option export function lookup(i: number, as?: ReadonlyArray): Option | ((as: ReadonlyArray) => Option) { - return as === undefined ? (as) => lookup(i, as) : isOutOfBound(i, as) ? O.none : O.some(as[i]) + return as === undefined ? (as) => lookup(i, as) : isOutOfBound(i, as) ? _.none : _.some(as[i]) } /** @@ -295,7 +386,7 @@ export function lookup(i: number, as?: ReadonlyArray): Option | ((as * * @since 2.5.0 */ -export const head = (as: ReadonlyArray): Option => (isNonEmpty(as) ? O.some(RNEA.head(as)) : O.none) +export const head = (as: ReadonlyArray): Option => (isNonEmpty(as) ? _.some(RNEA.head(as)) : _.none) /** * Get the last element in an array, or `None` if the array is empty @@ -309,7 +400,7 @@ export const head = (as: ReadonlyArray): Option => (isNonEmpty(as) ? O. * * @since 2.5.0 */ -export const last = (as: ReadonlyArray): Option => (isNonEmpty(as) ? O.some(RNEA.last(as)) : O.none) +export const last = (as: ReadonlyArray): Option => (isNonEmpty(as) ? _.some(RNEA.last(as)) : _.none) /** * Get all but the first element of an array, creating a new array, or `None` if the array is empty @@ -324,7 +415,7 @@ export const last = (as: ReadonlyArray): Option => (isNonEmpty(as) ? O. * @since 2.5.0 */ export const tail = (as: ReadonlyArray): Option> => - isNonEmpty(as) ? O.some(RNEA.tail(as)) : O.none + isNonEmpty(as) ? _.some(RNEA.tail(as)) : _.none /** * Get all but the last element of an array, creating a new array, or `None` if the array is empty @@ -339,7 +430,7 @@ export const tail = (as: ReadonlyArray): Option> => * @since 2.5.0 */ export const init = (as: ReadonlyArray): Option> => - isNonEmpty(as) ? O.some(RNEA.init(as)) : O.none + isNonEmpty(as) ? _.some(RNEA.init(as)) : _.none /** * Keep only a max number of elements from the start of an `ReadonlyArray`, creating a new `ReadonlyArray`. @@ -396,9 +487,10 @@ export const takeRight = (n: number) => (as: ReadonlyArray): ReadonlyArray * @since 2.5.0 */ export function takeLeftWhile(refinement: Refinement): (as: ReadonlyArray) => ReadonlyArray +export function takeLeftWhile(predicate: Predicate): (bs: ReadonlyArray) => ReadonlyArray export function takeLeftWhile(predicate: Predicate): (as: ReadonlyArray) => ReadonlyArray export function takeLeftWhile(predicate: Predicate): (as: ReadonlyArray) => ReadonlyArray { - return (as) => { + return (as: ReadonlyArray) => { const out: Array = [] for (const a of as) { if (!predicate(a)) { @@ -443,6 +535,7 @@ const spanLeftIndex = (as: ReadonlyArray, predicate: Predicate): number * @since 2.5.0 */ export function spanLeft(refinement: Refinement): (as: ReadonlyArray) => Spanned +export function spanLeft(predicate: Predicate): (bs: ReadonlyArray) => Spanned export function spanLeft(predicate: Predicate): (as: ReadonlyArray) => Spanned export function spanLeft(predicate: Predicate): (as: ReadonlyArray) => Spanned { return (as) => { @@ -502,9 +595,14 @@ export const dropRight = (n: number) => (as: ReadonlyArray): ReadonlyArray * @category combinators * @since 2.5.0 */ -export const dropLeftWhile = (predicate: Predicate) => (as: ReadonlyArray): ReadonlyArray => { - const i = spanLeftIndex(as, predicate) - return i === 0 ? as : i === as.length ? empty : as.slice(i) +export function dropLeftWhile(refinement: Refinement): (as: ReadonlyArray) => ReadonlyArray +export function dropLeftWhile(predicate: Predicate): (bs: ReadonlyArray) => ReadonlyArray +export function dropLeftWhile(predicate: Predicate): (as: ReadonlyArray) => ReadonlyArray +export function dropLeftWhile(predicate: Predicate): (as: ReadonlyArray) => ReadonlyArray { + return (as) => { + const i = spanLeftIndex(as, predicate) + return i === 0 ? as : i === as.length ? empty : as.slice(i) + } } /** @@ -522,10 +620,10 @@ export const dropLeftWhile = (predicate: Predicate) => (as: ReadonlyArray< export const findIndex = (predicate: Predicate) => (as: ReadonlyArray): Option => { for (let i = 0; i < as.length; i++) { if (predicate(as[i])) { - return O.some(i) + return _.some(i) } } - return O.none + return _.none } /** @@ -545,15 +643,16 @@ export const findIndex = (predicate: Predicate) => (as: ReadonlyArray): * @since 2.5.0 */ export function findFirst(refinement: Refinement): (as: ReadonlyArray) => Option +export function findFirst(predicate: Predicate): (bs: ReadonlyArray) => Option export function findFirst(predicate: Predicate): (as: ReadonlyArray) => Option export function findFirst(predicate: Predicate): (as: ReadonlyArray) => Option { return (as) => { for (let i = 0; i < as.length; i++) { if (predicate(as[i])) { - return O.some(as[i]) + return _.some(as[i]) } } - return O.none + return _.none } } @@ -579,11 +678,11 @@ export function findFirst(predicate: Predicate): (as: ReadonlyArray) => export const findFirstMap = (f: (a: A) => Option) => (as: ReadonlyArray): Option => { for (let i = 0; i < as.length; i++) { const out = f(as[i]) - if (O.isSome(out)) { + if (_.isSome(out)) { return out } } - return O.none + return _.none } /** @@ -603,15 +702,16 @@ export const findFirstMap = (f: (a: A) => Option) => (as: ReadonlyArray * @since 2.5.0 */ export function findLast(refinement: Refinement): (as: ReadonlyArray) => Option +export function findLast(predicate: Predicate): (bs: ReadonlyArray) => Option export function findLast(predicate: Predicate): (as: ReadonlyArray) => Option export function findLast(predicate: Predicate): (as: ReadonlyArray) => Option { return (as) => { for (let i = as.length - 1; i >= 0; i--) { if (predicate(as[i])) { - return O.some(as[i]) + return _.some(as[i]) } } - return O.none + return _.none } } @@ -637,11 +737,11 @@ export function findLast(predicate: Predicate): (as: ReadonlyArray) => export const findLastMap = (f: (a: A) => Option) => (as: ReadonlyArray): Option => { for (let i = as.length - 1; i >= 0; i--) { const out = f(as[i]) - if (O.isSome(out)) { + if (_.isSome(out)) { return out } } - return O.none + return _.none } /** @@ -665,10 +765,10 @@ export const findLastMap = (f: (a: A) => Option) => (as: ReadonlyArray< export const findLastIndex = (predicate: Predicate) => (as: ReadonlyArray): Option => { for (let i = as.length - 1; i >= 0; i--) { if (predicate(as[i])) { - return O.some(i) + return _.some(i) } } - return O.none + return _.none } /** @@ -682,9 +782,8 @@ export const findLastIndex = (predicate: Predicate) => (as: ReadonlyArray< * * @since 2.5.0 */ -export const insertAt: (i: number, a: A) => (as: ReadonlyArray) => O.Option> = - // tslint:disable-next-line: deprecation - RNEA.insertAt +export const insertAt = (i: number, a: A) => (as: ReadonlyArray): Option> => + i < 0 || i > as.length ? _.none : _.some(RNEA.unsafeInsertAt(i, a, as)) /** * Change the element at the specified index, creating a new array, or returning `None` if the index is out of bounds @@ -714,7 +813,7 @@ export const updateAt = (i: number, a: A): ((as: ReadonlyArray) => Option< * @since 2.5.0 */ export const deleteAt = (i: number) => (as: ReadonlyArray): Option> => - isOutOfBound(i, as) ? O.none : O.some(unsafeDeleteAt(i, as)) + isOutOfBound(i, as) ? _.none : _.some(unsafeDeleteAt(i, as)) /** * Apply a function to the element at the specified index, creating a new array, or returning `None` if the index is out @@ -731,7 +830,7 @@ export const deleteAt = (i: number) => (as: ReadonlyArray): Option(i: number, f: (a: A) => A) => (as: ReadonlyArray): Option> => - isOutOfBound(i, as) ? O.none : O.some(unsafeUpdateAt(i, f(as[i]), as)) + isOutOfBound(i, as) ? _.none : _.some(unsafeUpdateAt(i, f(as[i]), as)) /** * Reverse an array, creating a new array @@ -1087,6 +1186,14 @@ export const chunksOf = (n: number): ((as: ReadonlyArray) => ReadonlyArray return (as) => (isNonEmpty(as) ? f(as) : empty) } +/** + * @category combinators + * @since 2.11.0 + */ +export const fromOptionK = , B>(f: (...a: A) => Option) => ( + ...a: A +): ReadonlyArray => fromOption(f(...a)) + /** * `ReadonlyArray` comprehension. * @@ -1145,6 +1252,19 @@ export function comprehension( return go(empty, input) } +/** + * @category combinators + * @since 2.11.0 + */ +export const concatW = (second: ReadonlyArray) => (first: ReadonlyArray): ReadonlyArray => + isEmpty(first) ? second : isEmpty(second) ? first : (first as ReadonlyArray).concat(second) + +/** + * @category combinators + * @since 2.11.0 + */ +export const concat: (second: ReadonlyArray) => (first: ReadonlyArray) => ReadonlyArray = concatW + // TODO: remove non-curried overloading in v3 /** * Creates an array of unique values, in order, from all given arrays using a `Eq` for equality comparisons @@ -1172,9 +1292,9 @@ export function union( return (first, second?) => { if (second === undefined) { const unionE = union(E) - return (ys) => unionE(ys, first) + return (second) => unionE(second, first) } - return isNonEmpty(first) && isNonEmpty(second) ? unionE(first, second) : isNonEmpty(first) ? first : second + return isNonEmpty(first) && isNonEmpty(second) ? unionE(second)(first) : isNonEmpty(first) ? first : second } } @@ -1305,23 +1425,10 @@ const _traverseWithIndex: TraversableWithIndex1['traverseWithIndex' const traverseWithIndexF = traverseWithIndex(F) return (ta, f) => pipe(ta, traverseWithIndexF(f)) } -/* istanbul ignore next */ -const _wither: Witherable1['wither'] = ( - F: ApplicativeHKT -): ((ta: ReadonlyArray, f: (a: A) => HKT>) => HKT>) => { - const witherF = wither(F) - return (fa, f) => pipe(fa, witherF(f)) -} -/* istanbul ignore next */ -const _wilt: Witherable1['wilt'] = ( - F: ApplicativeHKT -): (( - fa: ReadonlyArray, - f: (a: A) => HKT> -) => HKT, ReadonlyArray>>) => { - const wiltF = wilt(F) - return (fa, f) => pipe(fa, wiltF(f)) -} +/** @internal */ +export const _chainRecDepthFirst: ChainRec1['chainRec'] = (a, f) => pipe(a, chainRecDepthFirst(f)) +/** @internal */ +export const _chainRecBreadthFirst: ChainRec1['chainRec'] = (a, f) => pipe(a, chainRecBreadthFirst(f)) // ------------------------------------------------------------------------------------- // type class members @@ -1334,10 +1441,10 @@ const _wilt: Witherable1['wilt'] = ( export const of: Pointed1['of'] = RNEA.of /** - * @category Alternative + * @category Zero * @since 2.7.0 */ -export const zero: Alternative1['zero'] = () => empty +export const zero: Zero1['zero'] = () => empty /** * Less strict version of [`alt`](#alt). @@ -1428,9 +1535,10 @@ export const separate = (fa: ReadonlyArray>): Separated(refinement: Refinement): (fa: ReadonlyArray) => ReadonlyArray - (predicate: Predicate): (fa: ReadonlyArray) => ReadonlyArray -} = (predicate: Predicate) => (fa: ReadonlyArray) => fa.filter(predicate) + (refinement: Refinement): (as: ReadonlyArray) => ReadonlyArray + (predicate: Predicate): (bs: ReadonlyArray) => ReadonlyArray + (predicate: Predicate): (as: ReadonlyArray) => ReadonlyArray +} = (predicate: Predicate) => (as: ReadonlyArray) => as.filter(predicate) /** * @category FilterableWithIndex @@ -1442,7 +1550,7 @@ export const filterMapWithIndex = (f: (i: number, a: A) => Option) => ( const out: Array = [] for (let i = 0; i < fa.length; i++) { const optionB = f(i, fa[i]) - if (O.isSome(optionB)) { + if (_.isSome(optionB)) { out.push(optionB.value) } } @@ -1470,10 +1578,11 @@ export const compact: (fa: ReadonlyArray>) => ReadonlyArray = */ export const partition: { (refinement: Refinement): ( - fa: ReadonlyArray + as: ReadonlyArray ) => Separated, ReadonlyArray> - (predicate: Predicate): (fa: ReadonlyArray) => Separated, ReadonlyArray> -} = (predicate: Predicate): ((fa: ReadonlyArray) => Separated, ReadonlyArray>) => + (predicate: Predicate): (bs: ReadonlyArray) => Separated, ReadonlyArray> + (predicate: Predicate): (as: ReadonlyArray) => Separated, ReadonlyArray> +} = (predicate: Predicate): ((as: ReadonlyArray) => Separated, ReadonlyArray>) => partitionWithIndex((_, a) => predicate(a)) /** @@ -1482,18 +1591,21 @@ export const partition: { */ export const partitionWithIndex: { (refinementWithIndex: RefinementWithIndex): ( - fa: ReadonlyArray + as: ReadonlyArray ) => Separated, ReadonlyArray> + (predicateWithIndex: PredicateWithIndex): ( + bs: ReadonlyArray + ) => Separated, ReadonlyArray> (predicateWithIndex: PredicateWithIndex): ( - fa: ReadonlyArray + as: ReadonlyArray ) => Separated, ReadonlyArray> } = (predicateWithIndex: PredicateWithIndex) => ( - fa: ReadonlyArray + as: ReadonlyArray ): Separated, ReadonlyArray> => { const left: Array = [] const right: Array = [] - for (let i = 0; i < fa.length; i++) { - const a = fa[i] + for (let i = 0; i < as.length; i++) { + const a = as[i] if (predicateWithIndex(i, a)) { right.push(a) } else { @@ -1537,10 +1649,11 @@ export const partitionMapWithIndex = (f: (i: number, a: A) => Either(refinementWithIndex: RefinementWithIndex): (fa: ReadonlyArray) => ReadonlyArray - (predicateWithIndex: PredicateWithIndex): (fa: ReadonlyArray) => ReadonlyArray -} = (predicateWithIndex: PredicateWithIndex) => (fa: ReadonlyArray): ReadonlyArray => - fa.filter((a, i) => predicateWithIndex(i, a)) + (refinementWithIndex: RefinementWithIndex): (as: ReadonlyArray) => ReadonlyArray + (predicateWithIndex: PredicateWithIndex): (bs: ReadonlyArray) => ReadonlyArray + (predicateWithIndex: PredicateWithIndex): (as: ReadonlyArray) => ReadonlyArray +} = (predicateWithIndex: PredicateWithIndex) => (as: ReadonlyArray): ReadonlyArray => + as.filter((a, i) => predicateWithIndex(i, a)) /** * @category Extend @@ -1661,8 +1774,8 @@ export const traverseWithIndex: PipeableTraverseWithIndex1 = (F: export const wither: PipeableWither1 = ( F: ApplicativeHKT ): ((f: (a: A) => HKT>) => (fa: ReadonlyArray) => HKT>) => { - const traverseF = traverse(F) - return (f) => (fa) => F.map(pipe(fa, traverseF(f)), compact) + const _witherF = _wither(F) + return (f) => (fa) => _witherF(fa, f) } /** @@ -1674,8 +1787,8 @@ export const wilt: PipeableWilt1 = ( ): (( f: (a: A) => HKT> ) => (fa: ReadonlyArray) => HKT, ReadonlyArray>>) => { - const traverseF = traverse(F) - return (f) => (fa) => F.map(pipe(fa, traverseF(f)), separate) + const _wiltF = _wilt(F) + return (f) => (fa) => _wiltF(fa, f) } /** @@ -1687,7 +1800,7 @@ export const unfold = (b: B, f: (b: B) => Option): Readon let bb: B = b while (true) { const mt = f(bb) - if (O.isSome(mt)) { + if (_.isSome(mt)) { const [a, b] = mt.value out.push(a) bb = b @@ -1805,6 +1918,48 @@ export const getOrd = (O: Ord): Ord> => return N.Ord.compare(aLen, bLen) }) +/** + * @category instances + * @since 2.11.0 + */ +export const getUnionSemigroup = (E: Eq): Semigroup> => { + const unionE = union(E) + return { + concat: (first, second) => unionE(second)(first) + } +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getUnionMonoid = (E: Eq): Monoid> => ({ + concat: getUnionSemigroup(E).concat, + empty +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const getIntersectionSemigroup = (E: Eq): Semigroup> => { + const intersectionE = intersection(E) + return { + concat: (first, second) => intersectionE(second)(first) + } +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getDifferenceMagma = (E: Eq): Magma> => { + const differenceE = difference(E) + return { + concat: (first, second) => differenceE(second)(first) + } +} + /** * @category instances * @since 2.7.0 @@ -1943,6 +2098,23 @@ export const Alt: Alt1 = { alt: _alt } +/** + * @category instances + * @since 2.11.0 + */ +export const Zero: Zero1 = { + URI, + zero +} + +/** + * @category constructors + * @since 2.11.0 + */ +export const guard = + /*#__PURE__*/ + guard_(Zero, Pointed) + /** * @category instances * @since 2.7.0 @@ -2069,6 +2241,81 @@ export const TraversableWithIndex: TraversableWithIndex1 = { traverseWithIndex: _traverseWithIndex } +/** + * @category ChainRec + * @since 2.11.0 + */ +export const chainRecDepthFirst = (f: (a: A) => ReadonlyArray>) => (a: A): ReadonlyArray => { + const todo: Array> = [...f(a)] + const out: Array = [] + + while (todo.length > 0) { + const e = todo.shift()! + if (_.isLeft(e)) { + todo.unshift(...f(e.left)) + } else { + out.push(e.right) + } + } + + return out +} + +/** + * @category instances + * @since 2.11.0 + */ +export const ChainRecDepthFirst: ChainRec1 = { + URI, + map: _map, + ap: _ap, + chain: _chain, + chainRec: _chainRecDepthFirst +} + +/** + * @category ChainRec + * @since 2.11.0 + */ +export const chainRecBreadthFirst = (f: (a: A) => ReadonlyArray>) => (a: A): ReadonlyArray => { + const initial = f(a) + const todo: Array> = [] + const out: Array = [] + + function go(e: Either): void { + if (_.isLeft(e)) { + f(e.left).forEach((v) => todo.push(v)) + } else { + out.push(e.right) + } + } + + for (const e of initial) { + go(e) + } + + while (todo.length > 0) { + go(todo.shift()!) + } + + return out +} + +/** + * @category instances + * @since 2.11.0 + */ +export const ChainRecBreadthFirst: ChainRec1 = { + URI, + map: _map, + ap: _ap, + chain: _chain, + chainRec: _chainRecBreadthFirst +} + +const _wither: Witherable1['wither'] = witherDefault(Traversable, Compactable) +const _wilt: Witherable1['wilt'] = wiltDefault(Traversable, Compactable) + /** * @category instances * @since 2.7.0 @@ -2091,6 +2338,49 @@ export const Witherable: Witherable1 = { wilt: _wilt } +/** + * Filter values inside a context. + * + * @example + * import { pipe } from 'fp-ts/function' + * import * as RA from 'fp-ts/ReadonlyArray' + * import * as T from 'fp-ts/Task' + * + * const filterE = RA.filterE(T.ApplicativePar) + * async function test() { + * assert.deepStrictEqual( + * await pipe( + * [-1, 2, 3], + * filterE((n) => T.of(n > 0)) + * )(), + * [2, 3] + * ) + * } + * test() + * + * @since 2.11.0 + */ +export const filterE = + /*#__PURE__*/ + filterE_(Witherable) + +/** + * @category instances + * @since 2.11.0 + */ +export const FromEither: FromEither1 = { + URI, + fromEither +} + +/** + * @category combinators + * @since 2.11.0 + */ +export const fromEitherK = + /*#__PURE__*/ + fromEitherK_(FromEither) + // ------------------------------------------------------------------------------------- // unsafe // ------------------------------------------------------------------------------------- @@ -2179,6 +2469,13 @@ export const every = (predicate: Predicate) => (as: ReadonlyArray): boo export const some = (predicate: Predicate) => (as: ReadonlyArray): as is ReadonlyNonEmptyArray => as.some(predicate) +/** + * Alias of [`some`](#some) + * + * @since 2.11.0 + */ +export const exists = some + // ------------------------------------------------------------------------------------- // do notation // ------------------------------------------------------------------------------------- @@ -2188,7 +2485,7 @@ export const some = (predicate: Predicate) => (as: ReadonlyArray): as i */ export const Do: ReadonlyArray<{}> = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 @@ -2219,6 +2516,17 @@ export const apS = // deprecated // ------------------------------------------------------------------------------------- +// tslint:disable: deprecation + +/** + * Use `ReadonlyNonEmptyArray` module instead. + * + * @category constructors + * @since 2.5.0 + * @deprecated + */ +export const range = RNEA.range + /** * Use [`prepend`](#prepend) instead. * @@ -2226,7 +2534,6 @@ export const apS = * @since 2.5.0 * @deprecated */ -// tslint:disable-next-line: deprecation export const cons = RNEA.cons /** @@ -2236,7 +2543,6 @@ export const cons = RNEA.cons * @since 2.5.0 * @deprecated */ -// tslint:disable-next-line: deprecation export const snoc = RNEA.snoc /** diff --git a/src/ReadonlyMap.ts b/src/ReadonlyMap.ts index 9ecf9765e..d4376010b 100644 --- a/src/ReadonlyMap.ts +++ b/src/ReadonlyMap.ts @@ -3,44 +3,45 @@ */ import { Applicative } from './Applicative' import { Compactable2 } from './Compactable' -import { Either, isLeft } from './Either' +import { Either } from './Either' import { Eq, fromEquals } from './Eq' import { Filterable2 } from './Filterable' import { FilterableWithIndex2C } from './FilterableWithIndex' import { Foldable, Foldable1, Foldable2, Foldable2C, Foldable3 } from './Foldable' import { FoldableWithIndex2C } from './FoldableWithIndex' -import { pipe, Predicate, Refinement } from './function' +import { pipe, SK } from './function' import { flap as flap_, Functor2 } from './Functor' import { FunctorWithIndex2C } from './FunctorWithIndex' import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT' +import * as _ from './internal' import { Magma } from './Magma' import { Monoid } from './Monoid' import * as O from './Option' import { Ord } from './Ord' +import { Predicate } from './Predicate' +import { Refinement } from './Refinement' import { Semigroup } from './Semigroup' import { Separated, separated } from './Separated' import { Show } from './Show' import { Traversable2C } from './Traversable' import { TraversableWithIndex2C } from './TraversableWithIndex' import { Unfoldable, Unfoldable1 } from './Unfoldable' -import { Witherable2C } from './Witherable' +import { wiltDefault, Witherable2C, witherDefault } from './Witherable' import Option = O.Option // ------------------------------------------------------------------------------------- -// model +// interop // ------------------------------------------------------------------------------------- /** - * @category constructors + * @category interop * @since 2.5.0 */ -export function fromMap(m: Map): ReadonlyMap { - return new Map(m) -} +export const fromMap = (m: Map): ReadonlyMap => new Map(m) /** - * @category destructors + * @category interop * @since 2.5.0 */ export function toMap(m: ReadonlyMap): Map { @@ -68,18 +69,14 @@ export function getShow(SK: Show, SA: Show): Show> * * @since 2.5.0 */ -export function size(d: ReadonlyMap): number { - return d.size -} +export const size = (m: ReadonlyMap): number => m.size /** * Test whether or not a map is empty * * @since 2.5.0 */ -export function isEmpty(d: ReadonlyMap): boolean { - return d.size === 0 -} +export const isEmpty = (m: ReadonlyMap): boolean => m.size === 0 // TODO: remove non-curried overloading in v3 /** @@ -100,7 +97,7 @@ export function member(E: Eq): (k: K, m?: ReadonlyMap) => boolean const memberE = member(E) return (m) => memberE(k, m) } - return O.isSome(lookupE(k, m)) + return _.isSome(lookupE(k, m)) } } @@ -198,7 +195,7 @@ export function toUnfoldable( return (d) => { const kas = toReadonlyArrayO(d) const len = kas.length - return U.unfold(0, (b) => (b < len ? O.some([kas[b], b + 1]) : O.none)) + return U.unfold(0, (b) => (b < len ? _.some([kas[b], b + 1]) : _.none)) } } @@ -214,7 +211,7 @@ export const upsertAt = (E: Eq): ((k: K, a: A) => (m: ReadonlyMap const lookupWithKeyEk = lookupWithKeyE(k) return (m) => { const found = lookupWithKeyEk(m) - if (O.isNone(found)) { + if (_.isNone(found)) { const out = new Map(m) out.set(k, a) return out @@ -238,7 +235,7 @@ export const deleteAt = (E: Eq): ((k: K) => (m: ReadonlyMap) => R const lookupWithKeyE = lookupWithKey(E) return (k) => (m) => { const found = lookupWithKeyE(k, m) - if (O.isSome(found)) { + if (_.isSome(found)) { const r = new Map(m) r.delete(found.value[0]) return r @@ -264,17 +261,17 @@ export const modifyAt = ( const lookupWithKeyE = lookupWithKey(E) return (k, f) => (m) => { const found = lookupWithKeyE(k, m) - if (O.isNone(found)) { - return O.none + if (_.isNone(found)) { + return _.none } const [fk, fv] = found.value const next = f(fv) if (next === fv) { - return O.some(m) + return _.some(m) } const r = new Map(m) r.set(fk, next) - return O.some(r) + return _.some(r) } } @@ -323,10 +320,10 @@ export function lookupWithKey( while (!(e = entries.next()).done) { const [ka, a] = e.value if (E.equals(ka, k)) { - return O.some([ka, a]) + return _.some([ka, a]) } } - return O.none + return _.none } } @@ -387,7 +384,7 @@ export function isSubmap( while (!(e = entries.next()).done) { const [k, a] = e.value const d2OptA = lookupWithKeyS(k, that) - if (O.isNone(d2OptA) || !SK.equals(k, d2OptA.value[0]) || !SA.equals(a, d2OptA.value[1])) { + if (_.isNone(d2OptA) || !SK.equals(k, d2OptA.value[0]) || !SA.equals(a, d2OptA.value[1])) { return false } } @@ -434,7 +431,7 @@ export function getMonoid(SK: Eq, SA: Semigroup): Monoid( const lookupWithKeyE = lookupWithKey(E) return F.reduce>(fka, new Map(), (b, [k, a]) => { const bOpt = lookupWithKeyE(k, b) - if (O.isSome(bOpt)) { + if (_.isSome(bOpt)) { b.set(bOpt.value[0], M.concat(bOpt.value[1], a)) } else { b.set(k, a) @@ -527,7 +524,7 @@ export const partitionMapWithIndex = (f: (k: K, a: A) => Either(f: (k: K, a: A) => Either(p: (k: K, a: A) => boolean) => ( - fa: ReadonlyMap -): Separated, ReadonlyMap> => { - const left = new Map() - const right = new Map() - const entries = fa.entries() - let e: Next - // tslint:disable-next-line: strict-boolean-expressions - while (!(e = entries.next()).done) { - const [k, a] = e.value - if (p(k, a)) { - right.set(k, a) - } else { - left.set(k, a) +export function partitionWithIndex( + predicateWithIndex: (k: K, a: A) => a is B +): (m: ReadonlyMap) => Separated, ReadonlyMap> +export function partitionWithIndex( + predicateWithIndex: (k: K, a: A) => boolean +): (m: ReadonlyMap) => Separated, ReadonlyMap> +export function partitionWithIndex( + predicateWithIndex: (k: K, a: A) => boolean +): (m: ReadonlyMap) => Separated, ReadonlyMap> +export function partitionWithIndex( + predicateWithIndex: (k: K, a: A) => boolean +): (m: ReadonlyMap) => Separated, ReadonlyMap> { + return (m: ReadonlyMap) => { + const left = new Map() + const right = new Map() + const entries = m.entries() + let e: Next + // tslint:disable-next-line: strict-boolean-expressions + while (!(e = entries.next()).done) { + const [k, a] = e.value + if (predicateWithIndex(k, a)) { + right.set(k, a) + } else { + left.set(k, a) + } } + return separated(left, right) } - return separated(left, right) } /** @@ -573,7 +581,7 @@ export const filterMapWithIndex = (f: (k: K, a: A) => Option) => ( while (!(e = entries.next()).done) { const [k, a] = e.value const o = f(k, a) - if (O.isSome(o)) { + if (_.isSome(o)) { m.set(k, o.value) } } @@ -584,18 +592,31 @@ export const filterMapWithIndex = (f: (k: K, a: A) => Option) => ( * @category combinators * @since 2.10.0 */ -export const filterWithIndex = (p: (k: K, a: A) => boolean) => (m: ReadonlyMap): ReadonlyMap => { - const out = new Map() - const entries = m.entries() - let e: Next - // tslint:disable-next-line: strict-boolean-expressions - while (!(e = entries.next()).done) { - const [k, a] = e.value - if (p(k, a)) { - out.set(k, a) +export function filterWithIndex( + predicateWithIndex: (k: K, a: A) => a is B +): (m: ReadonlyMap) => ReadonlyMap +export function filterWithIndex( + predicateWithIndex: (k: K, a: A) => boolean +): (m: ReadonlyMap) => ReadonlyMap +export function filterWithIndex( + predicateWithIndex: (k: K, a: A) => boolean +): (m: ReadonlyMap) => ReadonlyMap +export function filterWithIndex( + predicateWithIndex: (k: K, a: A) => boolean +): (m: ReadonlyMap) => ReadonlyMap { + return (m: ReadonlyMap) => { + const out = new Map() + const entries = m.entries() + let e: Next + // tslint:disable-next-line: strict-boolean-expressions + while (!(e = entries.next()).done) { + const [k, a] = e.value + if (predicateWithIndex(k, a)) { + out.set(k, a) + } } + return out } - return out } // ------------------------------------------------------------------------------------- @@ -631,7 +652,7 @@ export const compact = (fa: ReadonlyMap>): ReadonlyMap // tslint:disable-next-line: strict-boolean-expressions while (!(e = entries.next()).done) { const [k, oa] = e.value - if (O.isSome(oa)) { + if (_.isSome(oa)) { m.set(k, oa.value) } } @@ -644,6 +665,7 @@ export const compact = (fa: ReadonlyMap>): ReadonlyMap */ export const filter: { (refinement: Refinement): (fa: ReadonlyMap) => ReadonlyMap + (predicate: Predicate): (fb: ReadonlyMap) => ReadonlyMap (predicate: Predicate): (fa: ReadonlyMap) => ReadonlyMap } = (predicate: Predicate) => (fa: ReadonlyMap) => _filter(fa, predicate) @@ -680,6 +702,9 @@ export const partition: { (refinement: Refinement): ( fa: ReadonlyMap ) => Separated, ReadonlyMap> + (predicate: Predicate): ( + fb: ReadonlyMap + ) => Separated, ReadonlyMap> (predicate: Predicate): (fa: ReadonlyMap) => Separated, ReadonlyMap> } = (predicate: Predicate) => (fa: ReadonlyMap) => _partition(fa, predicate) @@ -705,7 +730,7 @@ export const separate = ( // tslint:disable-next-line: strict-boolean-expressions while (!(e = entries.next()).done) { const [k, ei] = e.value - if (isLeft(ei)) { + if (_.isLeft(ei)) { left.set(k, ei.left) } else { right.set(k, ei.right) @@ -736,6 +761,48 @@ declare module './HKT' { } } +/** + * @category instances + * @since 2.11.0 + */ +export const getUnionSemigroup = (E: Eq, S: Semigroup): Semigroup> => { + const unionES = union(E, S) + return { + concat: (first, second) => unionES(second)(first) + } +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getUnionMonoid = (E: Eq, S: Semigroup): Monoid> => ({ + concat: getUnionSemigroup(E, S).concat, + empty +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const getIntersectionSemigroup = (E: Eq, S: Semigroup): Semigroup> => { + const intersectionES = intersection(E, S) + return { + concat: (first, second) => intersectionES(second)(first) + } +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getDifferenceMagma = (E: Eq) => (): Magma> => { + const differenceE = difference(E) + return { + concat: (first, second) => differenceE(second)(first) + } +} + /** * @category instances * @since 2.5.0 @@ -814,73 +881,125 @@ export const Filterable: Filterable2 = { partitionMap: _partitionMap } +/** + * @since 2.11.0 + */ +export const reduce = (O: Ord): ((b: B, f: (b: B, a: A) => B) => (m: ReadonlyMap) => B) => { + const reduceWithIndexO = reduceWithIndex(O) + return (b, f) => reduceWithIndexO(b, (_, b, a) => f(b, a)) +} + +/** + * @since 2.11.0 + */ +export const foldMap = (O: Ord): ((M: Monoid) => (f: (a: A) => M) => (m: ReadonlyMap) => M) => { + const foldMapWithIndexO = foldMapWithIndex(O) + return (M) => { + const foldMapWithIndexOM = foldMapWithIndexO(M) + return (f) => foldMapWithIndexOM((_, a) => f(a)) + } +} + +/** + * @since 2.11.0 + */ +export const reduceRight = (O: Ord): ((b: B, f: (a: A, b: B) => B) => (m: ReadonlyMap) => B) => { + const reduceRightWithIndexO = reduceRightWithIndex(O) + return (b, f) => reduceRightWithIndexO(b, (_, b, a) => f(b, a)) +} + /** * @category instances * @since 2.10.0 */ export const getFoldable = (O: Ord): Foldable2C => { - const FWI = getFoldableWithIndex(O) + const reduceO = reduce(O) + const foldMapO = foldMap(O) + const reduceRightO = reduceRight(O) return { URI, _E: undefined as any, - reduce: FWI.reduce, - foldMap: FWI.foldMap, - reduceRight: FWI.reduceRight + reduce: (fa, b, f) => pipe(fa, reduceO(b, f)), + foldMap: (M) => { + const foldMapOM = foldMapO(M) + return (fa, f) => pipe(fa, foldMapOM(f)) + }, + reduceRight: (fa, b, f) => pipe(fa, reduceRightO(b, f)) } } /** - * @category instances - * @since 2.10.0 + * @since 2.11.0 */ -export const getFoldableWithIndex = (O: Ord): FoldableWithIndex2C => { +export const reduceWithIndex = ( + O: Ord +): ((b: B, f: (k: K, b: B, a: A) => B) => (m: ReadonlyMap) => B) => { const keysO = keys(O) - - const reduceWithIndex = (fa: ReadonlyMap, b: B, f: (k: K, b: B, a: A) => B): B => { - let out: B = b - const ks = keysO(fa) - const len = ks.length - for (let i = 0; i < len; i++) { - const k = ks[i] - out = f(k, out, fa.get(k)!) + return (b, f) => (m) => { + let out = b + for (const k of keysO(m)) { + out = f(k, out, m.get(k)!) } return out } +} - const foldMapWithIndex = (M: Monoid) => (fa: ReadonlyMap, f: (k: K, a: A) => M): M => { - let out: M = M.empty - const ks = keysO(fa) - const len = ks.length - for (let i = 0; i < len; i++) { - const k = ks[i] - out = M.concat(out, f(k, fa.get(k)!)) +/** + * @since 2.11.0 + */ +export const foldMapWithIndex = ( + O: Ord +): ((M: Monoid) => (f: (k: K, a: A) => M) => (m: ReadonlyMap) => M) => { + const keysO = keys(O) + return (M) => (f) => (m) => { + let out = M.empty + for (const k of keysO(m)) { + out = M.concat(out, f(k, m.get(k)!)) } return out } +} - const reduceRightWithIndex = (fa: ReadonlyMap, b: B, f: (k: K, a: A, b: B) => B): B => { - let out: B = b - const ks = keysO(fa) +/** + * @since 2.11.0 + */ +export const reduceRightWithIndex = ( + O: Ord +): ((b: B, f: (k: K, a: A, b: B) => B) => (m: ReadonlyMap) => B) => { + const keysO = keys(O) + return (b, f) => (m) => { + let out = b + const ks = keysO(m) const len = ks.length for (let i = len - 1; i >= 0; i--) { const k = ks[i] - out = f(k, fa.get(k)!, out) + out = f(k, m.get(k)!, out) } return out } +} +/** + * @category instances + * @since 2.10.0 + */ +export const getFoldableWithIndex = (O: Ord): FoldableWithIndex2C => { + const F = getFoldable(O) + const reduceWithIndexO = reduceWithIndex(O) + const foldMapWithIndexO = foldMapWithIndex(O) + const reduceRightWithIndexO = reduceRightWithIndex(O) return { URI, _E: undefined as any, - reduce: (fa, b, f) => reduceWithIndex(fa, b, (_, b, a) => f(b, a)), - foldMap: (M) => { - const foldMapWithIndexM = foldMapWithIndex(M) - return (fa, f) => foldMapWithIndexM(fa, (_, a) => f(a)) + reduce: F.reduce, + foldMap: F.foldMap, + reduceRight: F.reduceRight, + reduceWithIndex: (fa, b, f) => pipe(fa, reduceWithIndexO(b, f)), + foldMapWithIndex: (M) => { + const foldMapWithIndexOM = foldMapWithIndexO(M) + return (fa, f) => pipe(fa, foldMapWithIndexOM(f)) }, - reduceRight: (fa, b, f) => reduceRightWithIndex(fa, b, (_, a, b) => f(a, b)), - reduceWithIndex, - foldMapWithIndex, - reduceRightWithIndex + reduceRightWithIndex: (fa, b, f) => pipe(fa, reduceRightWithIndexO(b, f)) } } @@ -937,7 +1056,7 @@ export const getTraversableWithIndex = (O: Ord): TraversableWithIndex2C(F: Applicative): ((ta: ReadonlyMap>) => HKT>) => { const traverseWithIndexF = traverseWithIndex(F) - return (ta) => traverseWithIndexF(ta, (_, a) => a) + return (ta) => traverseWithIndexF(ta, SK) } return { URI, @@ -982,21 +1101,111 @@ export function getWitherable(O: Ord): Witherable2C & TraversableW foldMapWithIndex: TWI.foldMapWithIndex, reduceRightWithIndex: TWI.reduceRightWithIndex, traverseWithIndex: TWI.traverseWithIndex, - wilt: ( - F: Applicative - ): (( - wa: ReadonlyMap, - f: (a: A) => HKT> - ) => HKT, ReadonlyMap>>) => { - const traverseF = TWI.traverse(F) - return (wa, f) => F.map(traverseF(wa, f), separate) - }, - wither: ( - F: Applicative - ): ((wa: ReadonlyMap, f: (a: A) => HKT>) => HKT>) => { - const traverseF = TWI.traverse(F) - return (wa, f) => F.map(traverseF(wa, f), compact) + wilt: wiltDefault(TWI, Compactable), + wither: witherDefault(TWI, Compactable) + } +} + +// ------------------------------------------------------------------------------------- +// utils +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export const union = ( + E: Eq, + M: Magma +): ((second: ReadonlyMap) => (first: ReadonlyMap) => ReadonlyMap) => { + const lookupE = lookup(E) + return (second) => (first) => { + if (isEmpty(first)) { + return second + } + if (isEmpty(second)) { + return first + } + const out: Map = new Map() + const firstEntries = first.entries() + let e: Next + while (!(e = firstEntries.next()).done) { + const [k, a] = e.value + const oka = lookupE(k)(second) + if (_.isSome(oka)) { + out.set(k, M.concat(a, oka.value)) + } else { + out.set(k, a) + } + } + const secondEntries = second.entries() + while (!(e = secondEntries.next()).done) { + const [k, a] = e.value + const oka = lookupE(k)(out) + if (_.isNone(oka)) { + out.set(k, a) + } + } + return out + } +} + +/** + * @since 2.11.0 + */ +export const intersection = ( + E: Eq, + M: Magma +): ((second: ReadonlyMap) => (first: ReadonlyMap) => ReadonlyMap) => { + const lookupE = lookup(E) + return (second) => (first) => { + if (isEmpty(first) || isEmpty(second)) { + return empty + } + const out: Map = new Map() + const entries = first.entries() + let e: Next + while (!(e = entries.next()).done) { + const [k, a] = e.value + const oka = lookupE(k)(second) + if (_.isSome(oka)) { + out.set(k, M.concat(a, oka.value)) + } + } + return out + } +} + +/** + * @since 2.11.0 + */ +export const difference = ( + E: Eq +): ((_second: ReadonlyMap) => (first: ReadonlyMap) => ReadonlyMap) => { + const memberE = member(E) + return (second: ReadonlyMap) => (first: ReadonlyMap) => { + if (isEmpty(first)) { + return second + } + if (isEmpty(second)) { + return first } + const out: Map = new Map() + const firstEntries = first.entries() + let e: Next + while (!(e = firstEntries.next()).done) { + const [k, a] = e.value + if (!memberE(k)(second)) { + out.set(k, a) + } + } + const secondEntries = second.entries() + while (!(e = secondEntries.next()).done) { + const [k, a] = e.value + if (!memberE(k)(first)) { + out.set(k, a) + } + } + return out } } diff --git a/src/ReadonlyNonEmptyArray.ts b/src/ReadonlyNonEmptyArray.ts index 74af30e96..26de9b8b8 100644 --- a/src/ReadonlyNonEmptyArray.ts +++ b/src/ReadonlyNonEmptyArray.ts @@ -17,28 +17,30 @@ import { Applicative as ApplicativeHKT, Applicative1 } from './Applicative' import { apFirst as apFirst_, Apply1, apS as apS_, apSecond as apSecond_ } from './Apply' import { bind as bind_, Chain1, chainFirst as chainFirst_ } from './Chain' import { Comonad1 } from './Comonad' +import { Endomorphism } from './Endomorphism' import { Eq, fromEquals } from './Eq' import { Extend1 } from './Extend' import { Foldable1 } from './Foldable' import { FoldableWithIndex1 } from './FoldableWithIndex' -import { identity, Lazy, pipe, Predicate, Refinement } from './function' +import { identity, Lazy, pipe, SK } from './function' import { bindTo as bindTo_, flap as flap_, Functor1 } from './Functor' import { FunctorWithIndex1 } from './FunctorWithIndex' import { HKT } from './HKT' import * as _ from './internal' import { Monad1 } from './Monad' import { NonEmptyArray } from './NonEmptyArray' -import * as O from './Option' +import { Option } from './Option' import { getMonoid, Ord } from './Ord' import { Pointed1 } from './Pointed' +import { Predicate } from './Predicate' import { ReadonlyRecord } from './ReadonlyRecord' +import { Refinement } from './Refinement' import * as Se from './Semigroup' import { Show } from './Show' import { PipeableTraverse1, Traversable1 } from './Traversable' import { PipeableTraverseWithIndex1, TraversableWithIndex1 } from './TraversableWithIndex' import Semigroup = Se.Semigroup -import Option = O.Option // ------------------------------------------------------------------------------------- // model @@ -59,12 +61,12 @@ export type ReadonlyNonEmptyArray = ReadonlyArray & { /** * @internal */ -export const empty: ReadonlyArray = [] +export const empty: ReadonlyArray = _.emptyReadonlyArray /** * @internal */ -export const isNonEmpty = (as: ReadonlyArray): as is ReadonlyNonEmptyArray => as.length > 0 +export const isNonEmpty: (as: ReadonlyArray) => as is ReadonlyNonEmptyArray = _.isNonEmpty /** * @internal @@ -74,12 +76,22 @@ export const isOutOfBound = (i: number, as: ReadonlyArray): boolean => i < /** * @internal */ -export const prepend = (head: A) => (tail: ReadonlyArray): ReadonlyNonEmptyArray => [head, ...tail] +export const prependW = (head: B) => (tail: ReadonlyArray): ReadonlyNonEmptyArray => [head, ...tail] /** * @internal */ -export const append = (end: A) => (init: ReadonlyArray): ReadonlyNonEmptyArray => concat(init, [end]) +export const prepend: (head: A) => (tail: ReadonlyArray) => ReadonlyNonEmptyArray = prependW + +/** + * @internal + */ +export const appendW = (end: B) => (init: ReadonlyArray): ReadonlyNonEmptyArray => [...init, end] as any + +/** + * @internal + */ +export const append: (end: A) => (init: ReadonlyArray) => ReadonlyNonEmptyArray = appendW /** * @internal @@ -107,7 +119,16 @@ export const unsafeUpdateAt = (i: number, a: A, as: ReadonlyNonEmptyArray) } /** - * @internal + * Remove duplicates from a `ReadonlyNonEmptyArray`, keeping the first occurrence of an element. + * + * @example + * import { uniq } from 'fp-ts/ReadonlyNonEmptyArray' + * import * as N from 'fp-ts/number' + * + * assert.deepStrictEqual(uniq(N.Eq)([1, 2, 1]), [1, 2]) + * + * @category combinators + * @since 2.11.0 */ export const uniq = (E: Eq) => (as: ReadonlyNonEmptyArray): ReadonlyNonEmptyArray => { if (as.length === 1) { @@ -124,7 +145,43 @@ export const uniq = (E: Eq) => (as: ReadonlyNonEmptyArray): ReadonlyNon } /** - * @internal + * Sort the elements of a `ReadonlyNonEmptyArray` in increasing order, where elements are compared using first `ords[0]`, then `ords[1]`, + * etc... + * + * @example + * import * as RNEA from 'fp-ts/ReadonlyNonEmptyArray' + * import { contramap } from 'fp-ts/Ord' + * import * as S from 'fp-ts/string' + * import * as N from 'fp-ts/number' + * import { pipe } from 'fp-ts/function' + * + * interface Person { + * name: string + * age: number + * } + * + * const byName = pipe(S.Ord, contramap((p: Person) => p.name)) + * + * const byAge = pipe(N.Ord, contramap((p: Person) => p.age)) + * + * const sortByNameByAge = RNEA.sortBy([byName, byAge]) + * + * const persons: RNEA.ReadonlyNonEmptyArray = [ + * { name: 'a', age: 1 }, + * { name: 'b', age: 3 }, + * { name: 'c', age: 2 }, + * { name: 'b', age: 2 } + * ] + * + * assert.deepStrictEqual(sortByNameByAge(persons), [ + * { name: 'a', age: 1 }, + * { name: 'b', age: 2 }, + * { name: 'b', age: 3 }, + * { name: 'c', age: 2 } + * ]) + * + * @category combinators + * @since 2.11.0 */ export const sortBy = ( ords: ReadonlyArray> @@ -137,15 +194,27 @@ export const sortBy = ( } /** - * @internal + * @category combinators + * @since 2.11.0 */ -export const union = (E: Eq): Semigroup>['concat'] => { +export const union = ( + E: Eq +): ((second: ReadonlyNonEmptyArray) => (first: ReadonlyNonEmptyArray) => ReadonlyNonEmptyArray) => { const uniqE = uniq(E) - return (first, second) => uniqE(concat(first, second)) + return (second) => (first) => uniqE(pipe(first, concat(second))) } /** - * @internal + * Rotate a `ReadonlyNonEmptyArray` by `n` steps. + * + * @example + * import { rotate } from 'fp-ts/ReadonlyNonEmptyArray' + * + * assert.deepStrictEqual(rotate(2)([1, 2, 3, 4, 5]), [4, 5, 1, 2, 3]) + * assert.deepStrictEqual(rotate(-2)([1, 2, 3, 4, 5]), [3, 4, 5, 1, 2]) + * + * @category combinators + * @since 2.11.0 */ export const rotate = (n: number) => (as: ReadonlyNonEmptyArray): ReadonlyNonEmptyArray => { const len = as.length @@ -155,16 +224,41 @@ export const rotate = (n: number) => (as: ReadonlyNonEmptyArray): Readonly } if (m < 0) { const [f, s] = splitAt(-m)(as) - return concat(s, f) + return pipe(s, concat(f)) } else { return rotate(m - len)(as) } } +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- + /** - * @internal + * Return a `ReadonlyNonEmptyArray` from a `ReadonlyArray` returning `none` if the input is empty. + * + * @category constructors + * @since 2.5.0 */ -export const makeBy = (n: number, f: (i: number) => A): ReadonlyNonEmptyArray => { +export const fromReadonlyArray = (as: ReadonlyArray): Option> => + isNonEmpty(as) ? _.some(as) : _.none + +/** + * Return a `ReadonlyNonEmptyArray` of length `n` with element `i` initialized with `f(i)`. + * + * **Note**. `n` is normalized to a natural number. + * + * @example + * import { makeBy } from 'fp-ts/ReadonlyNonEmptyArray' + * import { pipe } from 'fp-ts/function' + * + * const double = (n: number): number => n * 2 + * assert.deepStrictEqual(pipe(5, makeBy(double)), [0, 2, 4, 6, 8]) + * + * @category constructors + * @since 2.11.0 + */ +export const makeBy = (f: (i: number) => A) => (n: number): ReadonlyNonEmptyArray => { const j = Math.max(0, Math.floor(n)) const out: NonEmptyArray = [f(0)] for (let i = 1; i < j; i++) { @@ -173,18 +267,35 @@ export const makeBy = (n: number, f: (i: number) => A): ReadonlyNonEmptyArray return out } -// ------------------------------------------------------------------------------------- -// constructors -// ------------------------------------------------------------------------------------- +/** + * Create a `ReadonlyNonEmptyArray` containing a value repeated the specified number of times. + * + * **Note**. `n` is normalized to a natural number. + * + * @example + * import { replicate } from 'fp-ts/ReadonlyNonEmptyArray' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual(pipe(3, replicate('a')), ['a', 'a', 'a']) + * + * @category constructors + * @since 2.11.0 + */ +export const replicate = (a: A): ((n: number) => ReadonlyNonEmptyArray) => makeBy(() => a) /** - * Return a `ReadonlyNonEmptyArray` from a `ReadonlyArray` returning `none` if the input is empty. + * Create a `ReadonlyNonEmptyArray` containing a range of integers, including both endpoints. + * + * @example + * import { range } from 'fp-ts/ReadonlyNonEmptyArray' + * + * assert.deepStrictEqual(range(1, 5), [1, 2, 3, 4, 5]) * * @category constructors - * @since 2.5.0 + * @since 2.11.0 */ -export const fromReadonlyArray = (as: ReadonlyArray): Option> => - isNonEmpty(as) ? O.some(as) : O.none +export const range = (start: number, end: number): ReadonlyNonEmptyArray => + start <= end ? makeBy((i) => start + i)(end - start + 1) : [start] // ------------------------------------------------------------------------------------- // destructors @@ -230,14 +341,35 @@ export const fromArray = (as: Array): Option> => // combinators // ------------------------------------------------------------------------------------- +/** + * @category combinators + * @since 2.11.0 + */ +export function concatW( + second: ReadonlyNonEmptyArray +): (first: ReadonlyArray) => ReadonlyNonEmptyArray +export function concatW( + second: ReadonlyArray +): (first: ReadonlyNonEmptyArray) => ReadonlyNonEmptyArray +export function concatW(second: ReadonlyArray): (first: ReadonlyNonEmptyArray) => ReadonlyArray { + return (first: ReadonlyNonEmptyArray) => first.concat(second) +} + /** * @category combinators * @since 2.5.0 */ +export function concat(second: ReadonlyNonEmptyArray): (first: ReadonlyArray) => ReadonlyNonEmptyArray +export function concat(second: ReadonlyArray): (first: ReadonlyNonEmptyArray) => ReadonlyNonEmptyArray +/** @deprecated */ export function concat(first: ReadonlyArray, second: ReadonlyNonEmptyArray): ReadonlyNonEmptyArray +/** @deprecated */ export function concat(first: ReadonlyNonEmptyArray, second: ReadonlyArray): ReadonlyNonEmptyArray -export function concat(first: ReadonlyArray, second: ReadonlyArray): ReadonlyArray { - return first.concat(second) +export function concat( + x: ReadonlyArray, + y?: ReadonlyArray +): ReadonlyArray | ((y: ReadonlyNonEmptyArray) => ReadonlyArray) { + return y ? x.concat(y) : (y) => y.concat(x) } /** @@ -293,30 +425,6 @@ export function group(E: Eq): (as: ReadonlyArray) => ReadonlyArray( - O: Ord -): { - (as: ReadonlyNonEmptyArray): ReadonlyNonEmptyArray> - (as: ReadonlyArray): ReadonlyArray> -} -export function groupSort(O: Ord): (as: ReadonlyArray) => ReadonlyArray> { - const sortO = sort(O) - const groupO = group(O) - return (as) => (isNonEmpty(as) ? groupO(sortO(as)) : empty) -} - /** * Splits an array into sub-non-empty-arrays stored in an object, based on the result of calling a `string`-returning * function on each element, and grouping the results according to values returned @@ -367,7 +475,7 @@ export const updateAt = (i: number, a: A): ((as: ReadonlyNonEmptyArray) => */ export const modifyAt = (i: number, f: (a: A) => A) => ( as: ReadonlyNonEmptyArray -): Option> => (isOutOfBound(i, as) ? O.none : O.some(unsafeUpdateAt(i, f(as[i]), as))) +): Option> => (isOutOfBound(i, as) ? _.none : _.some(unsafeUpdateAt(i, f(as[i]), as))) /** * @category combinators @@ -574,7 +682,7 @@ const _traverseWithIndex: TraversableWithIndex1['traverseWithIndex' * @category Pointed * @since 2.5.0 */ -export const of: Pointed1['of'] = (a) => [a] +export const of: Pointed1['of'] = _.singleton /** * Less strict version of [`alt`](#alt). @@ -584,7 +692,7 @@ export const of: Pointed1['of'] = (a) => [a] */ export const altW = (that: Lazy>) => ( as: ReadonlyNonEmptyArray -): ReadonlyNonEmptyArray => concat(as as ReadonlyNonEmptyArray, that()) +): ReadonlyNonEmptyArray => pipe(as, concatW(that())) /** * Identifies an associative operation on a type constructor. It is similar to `Semigroup`, except that it applies to @@ -740,7 +848,7 @@ export const traverse: PipeableTraverse1 = ( */ export const sequence: Traversable1['sequence'] = ( F: ApplicativeHKT -): ((as: ReadonlyNonEmptyArray>) => HKT>) => traverseWithIndex(F)((_, a) => a) +): ((as: ReadonlyNonEmptyArray>) => HKT>) => traverseWithIndex(F)(SK) /** * @category TraversableWithIndex @@ -763,7 +871,7 @@ export const traverseWithIndex: PipeableTraverseWithIndex1 = (F: * @category Comonad * @since 2.6.3 */ -export const extract: Comonad1['extract'] = (as) => as[0] +export const extract: Comonad1['extract'] = _.head // ------------------------------------------------------------------------------------- // instances @@ -820,6 +928,17 @@ export const getSemigroup = (): Semigroup> = export const getEq = (E: Eq): Eq> => fromEquals((xs, ys) => xs.length === ys.length && xs.every((x, i) => E.equals(x, ys[i]))) +/** + * @category combinators + * @since 2.11.0 + */ +export const getUnionSemigroup = (E: Eq): Semigroup> => { + const unionE = union(E) + return { + concat: (first, second) => unionE(second)(first) + } +} + /** * @category instances * @since 2.7.0 @@ -1027,7 +1146,7 @@ export const Comonad: Comonad1 = { */ export const Do: ReadonlyNonEmptyArray<{}> = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 @@ -1066,7 +1185,7 @@ export const head: (as: ReadonlyNonEmptyArray) => A = extract /** * @since 2.5.0 */ -export const tail = (as: ReadonlyNonEmptyArray): ReadonlyArray => as.slice(1) +export const tail: (as: ReadonlyNonEmptyArray) => ReadonlyArray = _.tail /** * @since 2.5.0 @@ -1107,10 +1226,83 @@ export const max = (O: Ord): ((as: ReadonlyNonEmptyArray) => A) => { */ export const concatAll = (S: Semigroup) => (as: ReadonlyNonEmptyArray): A => as.reduce(S.concat) +/** + * Break a `ReadonlyArray` into its first element and remaining elements. + * + * @category destructors + * @since 2.11.0 + */ +export const matchLeft = (f: (head: A, tail: ReadonlyArray) => B) => (as: ReadonlyNonEmptyArray): B => + f(head(as), tail(as)) + +/** + * Break a `ReadonlyArray` into its initial elements and the last element. + * + * @category destructors + * @since 2.11.0 + */ +export const matchRight = (f: (init: ReadonlyArray, last: A) => B) => (as: ReadonlyNonEmptyArray): B => + f(init(as), last(as)) + +/** + * Apply a function to the head, creating a new `ReadonlyNonEmptyArray`. + * + * @since 2.11.0 + */ +export const modifyHead = (f: Endomorphism) => (as: ReadonlyNonEmptyArray): ReadonlyNonEmptyArray => [ + f(head(as)), + ...tail(as) +] + +/** + * Change the head, creating a new `ReadonlyNonEmptyArray`. + * + * @category combinators + * @since 2.11.0 + */ +export const updateHead = (a: A): ((as: ReadonlyNonEmptyArray) => ReadonlyNonEmptyArray) => modifyHead(() => a) + +/** + * Apply a function to the last element, creating a new `ReadonlyNonEmptyArray`. + * + * @since 2.11.0 + */ +export const modifyLast = (f: Endomorphism) => (as: ReadonlyNonEmptyArray): ReadonlyNonEmptyArray => + pipe(init(as), append(f(last(as)))) + +/** + * Change the last element, creating a new `ReadonlyNonEmptyArray`. + * + * @category combinators + * @since 2.11.0 + */ +export const updateLast = (a: A): ((as: ReadonlyNonEmptyArray) => ReadonlyNonEmptyArray) => modifyLast(() => a) + // ------------------------------------------------------------------------------------- // deprecated // ------------------------------------------------------------------------------------- +// tslint:disable: deprecation + +/** + * This is just `sort` followed by `group`. + * + * @category combinators + * @since 2.5.0 + * @deprecated + */ +export function groupSort( + O: Ord +): { + (as: ReadonlyNonEmptyArray): ReadonlyNonEmptyArray> + (as: ReadonlyArray): ReadonlyArray> +} +export function groupSort(O: Ord): (as: ReadonlyArray) => ReadonlyArray> { + const sortO = sort(O) + const groupO = group(O) + return (as) => (isNonEmpty(as) ? groupO(sortO(as)) : empty) +} + /** * Use [`filter`](./ReadonlyArray.ts.html#filter) instead. * @@ -1121,14 +1313,16 @@ export const concatAll = (S: Semigroup) => (as: ReadonlyNonEmptyArray): export function filter( refinement: Refinement ): (as: ReadonlyNonEmptyArray) => Option> +export function filter( + predicate: Predicate +): (bs: ReadonlyNonEmptyArray) => Option> export function filter(predicate: Predicate): (as: ReadonlyNonEmptyArray) => Option> export function filter(predicate: Predicate): (as: ReadonlyNonEmptyArray) => Option> { - // tslint:disable-next-line: deprecation return filterWithIndex((_, a) => predicate(a)) } /** - * Use [`filterWithIndex`](./ReadonlyArray.ts.html#filterWithIndex) instead. + * Use [`filterWithIndex`](./ReadonlyArray.ts.html#filterwithindex) instead. * * @category combinators * @since 2.5.0 @@ -1180,17 +1374,17 @@ export function cons( * @since 2.5.0 * @deprecated */ -export const snoc = (init: ReadonlyArray, end: A): ReadonlyNonEmptyArray => concat(init, [end]) +export const snoc = (init: ReadonlyArray, end: A): ReadonlyNonEmptyArray => pipe(init, concat([end])) /** - * Use [`insertAt`](./ReadonlyArray.ts.html#insertAt) instead. + * Use [`insertAt`](./ReadonlyArray.ts.html#insertat) instead. * * @category combinators * @since 2.5.0 * @deprecated */ export const insertAt = (i: number, a: A) => (as: ReadonlyArray): Option> => - i < 0 || i > as.length ? O.none : O.some(unsafeInsertAt(i, a, as)) + i < 0 || i > as.length ? _.none : _.some(unsafeInsertAt(i, a, as)) /** * Use [`prependAll`](#prependall) instead. diff --git a/src/ReadonlyRecord.ts b/src/ReadonlyRecord.ts index d0b8394d4..698f6a276 100644 --- a/src/ReadonlyRecord.ts +++ b/src/ReadonlyRecord.ts @@ -9,23 +9,25 @@ import { Filterable1 } from './Filterable' import { FilterableWithIndex1, PredicateWithIndex, RefinementWithIndex } from './FilterableWithIndex' import { Foldable as FoldableHKT, Foldable1, Foldable2, Foldable3 } from './Foldable' import { FoldableWithIndex1 } from './FoldableWithIndex' -import { identity, pipe, Predicate, Refinement } from './function' +import { flow, identity, pipe, SK } from './function' import { flap as flap_, Functor1 } from './Functor' import { FunctorWithIndex1 } from './FunctorWithIndex' import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT' import * as _ from './internal' import { Magma } from './Magma' import { Monoid } from './Monoid' -import * as O from './Option' +import { Option } from './Option' +import { Ord } from './Ord' +import { Predicate } from './Predicate' +import { Refinement } from './Refinement' import { Semigroup } from './Semigroup' import { Separated, separated } from './Separated' import { Show } from './Show' +import * as S from './string' import { Traversable1 } from './Traversable' import { TraversableWithIndex1 } from './TraversableWithIndex' import { Unfoldable, Unfoldable1 } from './Unfoldable' -import { PipeableWilt1, PipeableWither1, Witherable1 } from './Witherable' - -import Option = O.Option +import { PipeableWilt1, PipeableWither1, wiltDefault, Witherable1, witherDefault } from './Witherable' // ------------------------------------------------------------------------------------- // model @@ -45,31 +47,27 @@ export type ReadonlyRecord = Readonly> * @category interop * @since 2.5.0 */ -export function fromRecord(r: Record): ReadonlyRecord { - return Object.assign({}, r) -} +export const fromRecord = (r: Record): ReadonlyRecord => Object.assign({}, r) /** * @category interop * @since 2.5.0 */ -export function toRecord(r: ReadonlyRecord): Record { - return Object.assign({}, r) -} +export const toRecord = (r: ReadonlyRecord): Record => Object.assign({}, r) /** * Calculate the number of key/value pairs in a `ReadonlyRecord`, * * @since 2.5.0 */ -export const size = (r: ReadonlyRecord): number => Object.keys(r).length +export const size = (r: ReadonlyRecord): number => Object.keys(r).length /** * Test whether a `ReadonlyRecord` is empty. * * @since 2.5.0 */ -export const isEmpty = (r: ReadonlyRecord): boolean => { +export const isEmpty = (r: ReadonlyRecord): boolean => { for (const k in r) { if (_.has.call(r, k)) { return false @@ -78,34 +76,56 @@ export const isEmpty = (r: ReadonlyRecord): boolean => { return true } +const keys_ = (O: Ord) => (r: ReadonlyRecord): ReadonlyArray => + (Object.keys(r) as any).sort(O.compare) + /** * @since 2.5.0 */ -export const keys = (r: ReadonlyRecord): ReadonlyArray => - (Object.keys(r) as any).sort() +export const keys: (r: ReadonlyRecord) => ReadonlyArray = + /*#__PURE__*/ + keys_(S.Ord) /** * Map a `ReadonlyRecord` into an `ReadonlyArray`. * * @example * import { collect } from 'fp-ts/ReadonlyRecord' + * import { Ord } from 'fp-ts/string' * * const x: { readonly a: string, readonly b: boolean } = { a: 'c', b: false } * assert.deepStrictEqual( - * collect((key, val) => ({ key: key, value: val }))(x), + * collect(Ord)((key, val) => ({ key: key, value: val }))(x), * [{ key: 'a', value: 'c' }, { key: 'b', value: false }] * ) * * @since 2.5.0 */ -export const collect = (f: (k: K, a: A) => B) => ( - r: ReadonlyRecord -): ReadonlyArray => { - const out: Array = [] - for (const key of keys(r)) { - out.push(f(key, r[key])) +export function collect( + O: Ord +): (f: (k: K, a: A) => B) => (r: ReadonlyRecord) => ReadonlyArray +/** + * Use the overload constrained by `Ord` instead. + * + * @deprecated + */ +export function collect(f: (k: K, a: A) => B): (r: ReadonlyRecord) => ReadonlyArray +export function collect( + O: Ord | ((k: string, a: A) => B) +): + | ((f: (k: K, a: A) => B) => (r: ReadonlyRecord) => ReadonlyArray) + | ((r: ReadonlyRecord) => ReadonlyArray) { + if (typeof O === 'function') { + return collect(S.Ord)(O) + } + const keysO = keys_(O) + return (f: (k: K, a: A) => B) => (r: ReadonlyRecord) => { + const out: Array = [] + for (const key of keysO(r)) { + out.push(f(key, r[key])) + } + return out } - return out } /** @@ -115,7 +135,7 @@ export const collect = (f: (k: K, a: A) => B) => ( */ export const toReadonlyArray: (r: ReadonlyRecord) => ReadonlyArray = /*#__PURE__*/ - collect((k, a) => [k, a]) + collect(S.Ord)((k, a) => [k, a]) /** * Unfolds a `ReadonlyRecord` into a list of key/value pairs. @@ -133,7 +153,7 @@ export function toUnfoldable(U: Unfoldable): (r: ReadonlyRecord { const sas = toReadonlyArray(r) const len = sas.length - return U.unfold(0, (b) => (b < len ? O.some([sas[b], b + 1]) : O.none)) + return U.unfold(0, (b) => (b < len ? _.some([sas[b], b + 1]) : _.none)) } } @@ -155,7 +175,7 @@ export const upsertAt = (k: string, a: A) => (r: ReadonlyRecord): /** * Test whether or not a key exists in a `ReadonlyRecord`. * - * Note. This function is not pipeable because is a custom type guard. + * Note. This function is not pipeable because is a `Refinement`. * * @since 2.10.0 */ @@ -188,14 +208,14 @@ export const updateAt = (k: string, a: A) => ( r: ReadonlyRecord ): Option> => { if (!has(k, r)) { - return O.none + return _.none } if (r[k] === a) { - return O.some(r) + return _.some(r) } const out: Record = Object.assign({}, r) out[k] = a - return O.some(out) + return _.some(out) } /** @@ -205,15 +225,15 @@ export const modifyAt = (k: string, f: (a: A) => A) => ( r: ReadonlyRecord ): Option> => { if (!has(k, r)) { - return O.none + return _.none } const next = f(r[k]) if (next === r[k]) { - return O.some(r) + return _.some(r) } const out: Record = Object.assign({}, r) out[k] = next - return O.some(out) + return _.some(out) } /** @@ -230,7 +250,7 @@ export function pop(k: string): (r: ReadonlyRecord) => Option { const oa = lookup(k, r) - return O.isNone(oa) ? O.none : O.some([oa.value, deleteAtk(r)]) + return _.isNone(oa) ? _.none : _.some([oa.value, deleteAtk(r)]) } } @@ -281,7 +301,7 @@ export function lookup( if (r === undefined) { return (r) => lookup(k, r) } - return _.has.call(r, k) ? O.some(r[k]) : O.none + return _.has.call(r, k) ? _.some(r[k]) : _.none } /** @@ -326,14 +346,30 @@ export function map(f: (a: A) => B): (fa: ReadonlyRecord) => Re /** * @since 2.5.0 */ +export function reduceWithIndex( + O: Ord +): (b: B, f: (k: K, b: B, a: A) => B) => (fa: ReadonlyRecord) => B +/** + * Use the overload constrained by `Ord` instead. + * + * @deprecated + */ export function reduceWithIndex( b: B, f: (k: K, b: B, a: A) => B ): (fa: ReadonlyRecord) => B -export function reduceWithIndex(b: B, f: (k: string, b: B, a: A) => B): (fa: ReadonlyRecord) => B { - return (fa) => { - let out = b - const ks = keys(fa) +export function reduceWithIndex( + ...args: [Ord] | [B, (k: string, b: B, a: A) => B] +): + | ((b: B, f: (k: string, b: B, a: A) => B) => (fa: ReadonlyRecord) => B) + | ((fa: ReadonlyRecord) => B) { + if (args.length === 2) { + return reduceWithIndex(S.Ord)(...args) + } + const keysO = keys_(args[0]) + return (b, f) => (fa) => { + let out: B = b + const ks = keysO(fa) const len = ks.length for (let i = 0; i < len; i++) { const k = ks[i] @@ -346,38 +382,65 @@ export function reduceWithIndex(b: B, f: (k: string, b: B, a: A) => B): (f /** * @since 2.5.0 */ +export function foldMapWithIndex( + O: Ord +): (M: Monoid) => (f: (k: K, a: A) => M) => (fa: ReadonlyRecord) => M +/** + * Use the overload constrained by `Ord` instead. + * + * @deprecated + */ export function foldMapWithIndex( M: Monoid ): (f: (k: K, a: A) => M) => (fa: ReadonlyRecord) => M export function foldMapWithIndex( - M: Monoid -): (f: (k: string, a: A) => M) => (fa: ReadonlyRecord) => M { - return (f) => (fa) => { - let out = M.empty - const ks = keys(fa) - const len = ks.length - for (let i = 0; i < len; i++) { - const k = ks[i] - out = M.concat(out, f(k, fa[k])) + O: Ord | Monoid +): + | ((M: Monoid) => (f: (k: string, a: A) => M) => (fa: ReadonlyRecord) => M) + | ((f: (k: string, a: A) => M) => (fa: ReadonlyRecord) => M) { + if ('compare' in O) { + const keysO = keys_(O) + return (M: Monoid) => (f: (k: string, a: A) => M) => (fa: ReadonlyRecord) => { + let out: M = M.empty + const ks = keysO(fa) + const len = ks.length + for (let i = 0; i < len; i++) { + const k = ks[i] + out = M.concat(out, f(k, fa[k])) + } + return out } - return out } + return foldMapWithIndex(S.Ord)(O) } /** * @since 2.5.0 */ +export function reduceRightWithIndex( + O: Ord +): (b: B, f: (k: K, a: A, b: B) => B) => (fa: ReadonlyRecord) => B +/** + * Use the overload constrained by `Ord` instead. + * + * @deprecated + */ export function reduceRightWithIndex( b: B, f: (k: K, a: A, b: B) => B ): (fa: ReadonlyRecord) => B export function reduceRightWithIndex( - b: B, - f: (k: string, a: A, b: B) => B -): (fa: ReadonlyRecord) => B { - return (fa) => { - let out = b - const ks = keys(fa) + ...args: [Ord] | [B, (k: string, a: A, b: B) => B] +): + | ((b: B, f: (k: string, a: A, b: B) => B) => (fa: ReadonlyRecord) => B) + | ((fa: ReadonlyRecord) => B) { + if (args.length === 2) { + return reduceRightWithIndex(S.Ord)(...args) + } + const keysO = keys_(args[0]) + return (b, f) => (fa) => { + let out: B = b + const ks = keysO(fa) const len = ks.length for (let i = len - 1; i >= 0; i--) { const k = ks[i] @@ -429,23 +492,8 @@ export function traverseWithIndex( export function traverseWithIndex( F: Applicative ): (f: (k: string, a: A) => HKT) => (ta: ReadonlyRecord) => HKT> { - return (f: (k: string, a: A) => HKT) => (ta: ReadonlyRecord) => { - const ks = keys(ta) - if (ks.length === 0) { - return F.of(empty) - } - let fr: HKT> = F.of({}) - for (const key of ks) { - fr = F.ap( - F.map(fr, (r) => (b: B) => { - r[key] = b - return r - }), - f(key, ta[key]) - ) - } - return fr - } + const traverseWithIndexOF = _traverseWithIndex(S.Ord)(F) + return (f) => (ta) => traverseWithIndexOF(ta, f) } /** @@ -480,8 +528,8 @@ export function traverse( export function traverse( F: Applicative ): (f: (a: A) => HKT) => (ta: ReadonlyRecord) => HKT> { - const traverseWithIndexF = traverseWithIndex(F) - return (f) => traverseWithIndexF((_, a) => f(a)) + const traverseOF = _traverse(S.Ord)(F) + return (f) => (ta) => traverseOF(ta, f) } /** @@ -508,7 +556,7 @@ export function sequence( export function sequence( F: Applicative ): (ta: ReadonlyRecord>) => HKT> { - return traverseWithIndex(F)((_, a) => a) + return _sequence(S.Ord)(F) } /** @@ -570,6 +618,9 @@ export function partitionMapWithIndex( export function partitionWithIndex( refinementWithIndex: RefinementWithIndex ): (fa: ReadonlyRecord) => Separated, ReadonlyRecord> +export function partitionWithIndex( + predicateWithIndex: PredicateWithIndex +): (fb: ReadonlyRecord) => Separated, ReadonlyRecord> export function partitionWithIndex( predicateWithIndex: PredicateWithIndex ): (fa: ReadonlyRecord) => Separated, ReadonlyRecord> @@ -623,6 +674,9 @@ export function filterMapWithIndex( export function filterWithIndex( refinementWithIndex: RefinementWithIndex ): (fa: ReadonlyRecord) => ReadonlyRecord +export function filterWithIndex( + predicateWithIndex: PredicateWithIndex +): (fb: ReadonlyRecord) => ReadonlyRecord export function filterWithIndex( predicateWithIndex: PredicateWithIndex ): (fa: ReadonlyRecord) => ReadonlyRecord @@ -795,89 +849,208 @@ export function elem( } } +/** + * @category combinators + * @since 2.11.0 + */ +export const union = (M: Magma) => (second: ReadonlyRecord) => ( + first: ReadonlyRecord +): ReadonlyRecord => { + if (isEmpty(first)) { + return second + } + if (isEmpty(second)) { + return first + } + const out: Record = {} + for (const k in first) { + if (has(k, second)) { + out[k] = M.concat(first[k], second[k]) + } else { + out[k] = first[k] + } + } + for (const k in second) { + if (!has(k, out)) { + out[k] = second[k] + } + } + return out +} + +/** + * @category combinators + * @since 2.11.0 + */ +export const intersection = (M: Magma) => (second: ReadonlyRecord) => ( + first: ReadonlyRecord +): ReadonlyRecord => { + if (isEmpty(first) || isEmpty(second)) { + return empty + } + const out: Record = {} + for (const k in first) { + if (has(k, second)) { + out[k] = M.concat(first[k], second[k]) + } + } + return out +} + +/** + * @category combinators + * @since 2.11.0 + */ +export const difference = (second: ReadonlyRecord) => ( + first: ReadonlyRecord +): ReadonlyRecord => { + if (isEmpty(first)) { + return second + } + if (isEmpty(second)) { + return first + } + const out: Record = {} + for (const k in first) { + if (!has(k, second)) { + out[k] = first[k] + } + } + for (const k in second) { + if (!has(k, first)) { + out[k] = second[k] + } + } + return out +} + // ------------------------------------------------------------------------------------- // non-pipeables // ------------------------------------------------------------------------------------- -const _map: Functor1['map'] = (fa, f) => pipe(fa, map(f)) -/* istanbul ignore next */ -const _mapWithIndex: FunctorWithIndex1['mapWithIndex'] = (fa, f) => pipe(fa, mapWithIndex(f)) +/** @internal */ +export const _map: Functor1['map'] = (fa, f) => pipe(fa, map(f)) +/** @internal */ /* istanbul ignore next */ -const _reduce: Foldable1['reduce'] = (fa, b, f) => pipe(fa, reduce(b, f)) +export const _mapWithIndex: FunctorWithIndex1['mapWithIndex'] = (fa, f) => pipe(fa, mapWithIndex(f)) +/** @internal */ /* istanbul ignore next */ -const _foldMap: Foldable1['foldMap'] = (M) => { - const foldMapM = foldMap(M) +export const _reduce: (O: Ord) => Foldable1['reduce'] = (O: Ord) => { + const reduceO = reduce(O) + return (fa, b, f) => pipe(fa, reduceO(b, f)) +} +/** @internal */ +export const _foldMap: (O: Ord) => Foldable1['foldMap'] = (O) => (M) => { + const foldMapM = foldMap(O)(M) return (fa, f) => pipe(fa, foldMapM(f)) } +/** @internal */ /* istanbul ignore next */ -const _reduceRight: Foldable1['reduceRight'] = (fa, b, f) => pipe(fa, reduceRight(b, f)) -/* istanbul ignore next */ -const _traverse = ( - F: Applicative -): ((ta: ReadonlyRecord, f: (a: A) => HKT) => HKT>) => { - const traverseF = traverse(F) - return (ta, f) => pipe(ta, traverseF(f)) +export const _reduceRight: (O: Ord) => Foldable1['reduceRight'] = (O) => { + const reduceRightO = reduceRight(O) + return (fa, b, f) => pipe(fa, reduceRightO(b, f)) } +/** @internal */ /* istanbul ignore next */ -const _filter = (fa: ReadonlyRecord, predicate: Predicate): ReadonlyRecord => +export const _filter = (fa: ReadonlyRecord, predicate: Predicate): ReadonlyRecord => pipe(fa, filter(predicate)) +/** @internal */ /* istanbul ignore next */ -const _filterMap: Filterable1['filterMap'] = (fa, f) => pipe(fa, filterMap(f)) +export const _filterMap: Filterable1['filterMap'] = (fa, f) => pipe(fa, filterMap(f)) +/** @internal */ /* istanbul ignore next */ -const _partition = ( +export const _partition = ( fa: ReadonlyRecord, predicate: Predicate ): Separated, ReadonlyRecord> => pipe(fa, partition(predicate)) +/** @internal */ /* istanbul ignore next */ -const _partitionMap: Filterable1['partitionMap'] = (fa, f) => pipe(fa, partitionMap(f)) +export const _partitionMap: Filterable1['partitionMap'] = (fa, f) => pipe(fa, partitionMap(f)) +/** @internal */ /* istanbul ignore next */ -const _reduceWithIndex: FoldableWithIndex1['reduceWithIndex'] = (fa, b, f) => - pipe(fa, reduceWithIndex(b, f)) -/* istanbul ignore next */ -const _foldMapWithIndex: FoldableWithIndex1['foldMapWithIndex'] = (M) => { - const foldMapWithIndexM = foldMapWithIndex(M) - return (fa, f) => pipe(fa, foldMapWithIndexM(f)) +export const _reduceWithIndex: (O: Ord) => FoldableWithIndex1['reduceWithIndex'] = (O) => { + const reduceWithIndexO = reduceWithIndex(O) + return (fa, b, f) => pipe(fa, reduceWithIndexO(b, f)) } +/** @internal */ +export const _foldMapWithIndex: (O: Ord) => FoldableWithIndex1['foldMapWithIndex'] = (O) => { + const foldMapWithIndexO = foldMapWithIndex(O) + return (M) => { + const foldMapWithIndexM = foldMapWithIndexO(M) + return (fa, f) => pipe(fa, foldMapWithIndexM(f)) + } +} +/** @internal */ /* istanbul ignore next */ -const _reduceRightWithIndex: FoldableWithIndex1['reduceRightWithIndex'] = (fa, b, f) => - pipe(fa, reduceRightWithIndex(b, f)) +export const _reduceRightWithIndex: (O: Ord) => FoldableWithIndex1['reduceRightWithIndex'] = ( + O +) => { + const reduceRightWithIndexO = reduceRightWithIndex(O) + return (fa, b, f) => pipe(fa, reduceRightWithIndexO(b, f)) +} +/** @internal */ /* istanbul ignore next */ -const _partitionMapWithIndex = ( +export const _partitionMapWithIndex = ( fa: ReadonlyRecord, f: (key: string, a: A) => Either -): Separated>, Readonly>> => pipe(fa, partitionMapWithIndex(f)) +): Separated, ReadonlyRecord> => pipe(fa, partitionMapWithIndex(f)) +/** @internal */ /* istanbul ignore next */ -const _partitionWithIndex = (fa: ReadonlyRecord, predicateWithIndex: PredicateWithIndex) => - pipe(fa, partitionWithIndex(predicateWithIndex)) +export const _partitionWithIndex = ( + fa: ReadonlyRecord, + predicateWithIndex: PredicateWithIndex +) => pipe(fa, partitionWithIndex(predicateWithIndex)) +/** @internal */ /* istanbul ignore next */ -const _filterMapWithIndex = (fa: ReadonlyRecord, f: (key: string, a: A) => Option) => +export const _filterMapWithIndex = (fa: ReadonlyRecord, f: (key: string, a: A) => Option) => pipe(fa, filterMapWithIndex(f)) +/** @internal */ /* istanbul ignore next */ -const _filterWithIndex = (fa: ReadonlyRecord, predicateWithIndex: PredicateWithIndex) => +export const _filterWithIndex = (fa: ReadonlyRecord, predicateWithIndex: PredicateWithIndex) => pipe(fa, filterWithIndex(predicateWithIndex)) -/* istanbul ignore next */ -const _traverseWithIndex = ( +/** @internal */ +export const _traverse = ( + O: Ord +): (( F: Applicative -): ((ta: ReadonlyRecord, f: (k: string, a: A) => HKT) => HKT>) => { - const traverseWithIndexF = traverseWithIndex(F) - return (ta, f) => pipe(ta, traverseWithIndexF(f)) +) => (ta: ReadonlyRecord, f: (a: A) => HKT) => HKT>) => { + const traverseWithIndexO = _traverseWithIndex(O) + return (F) => { + const traverseWithIndexOF = traverseWithIndexO(F) + return (ta, f) => traverseWithIndexOF(ta, flow(SK, f)) + } } -/* istanbul ignore next */ -const _wither = ( - F: Applicative -): ((fa: ReadonlyRecord, f: (a: A) => HKT>) => HKT>) => { - const witherF = wither(F) - return (fa, f) => pipe(fa, witherF(f)) +/** @internal */ +export const _sequence = ( + O: Ord +): ((F: Applicative) => (ta: ReadonlyRecord>) => HKT>) => { + const traverseO = _traverse(O) + return (F) => { + const traverseOF = traverseO(F) + return (ta) => traverseOF(ta, identity) + } } -/* istanbul ignore next */ -const _wilt = ( +const _traverseWithIndex = (O: Ord) => ( F: Applicative -): (( - fa: ReadonlyRecord, - f: (a: A) => HKT> -) => HKT, ReadonlyRecord>>) => { - const wiltF = wilt(F) - return (fa, f) => pipe(fa, wiltF(f)) +): ((ta: ReadonlyRecord, f: (k: string, a: A) => HKT) => HKT>) => { + const keysO = keys_(O) + return (ta: ReadonlyRecord, f: (k: string, a: A) => HKT) => { + const ks = keysO(ta) + if (ks.length === 0) { + return F.of(empty) + } + let fr: HKT> = F.of({}) + for (const key of ks) { + fr = F.ap( + F.map(fr, (r) => (b: B) => { + r[key] = b + return r + }), + f(key, ta[key]) + ) + } + return fr + } } // ------------------------------------------------------------------------------------- @@ -889,9 +1062,10 @@ const _wilt = ( * @since 2.5.0 */ export const filter: { - (refinement: Refinement): (fa: Readonly>) => Readonly> - (predicate: Predicate): (fa: Readonly>) => Readonly> -} = (predicate: Predicate): ((fa: Readonly>) => Readonly>) => + (refinement: Refinement): (fa: ReadonlyRecord) => ReadonlyRecord + (predicate: Predicate): (fb: ReadonlyRecord) => ReadonlyRecord + (predicate: Predicate): (fa: ReadonlyRecord) => ReadonlyRecord +} = (predicate: Predicate): ((fa: ReadonlyRecord) => ReadonlyRecord) => filterWithIndex((_, a) => predicate(a)) /** @@ -900,7 +1074,7 @@ export const filter: { */ export const filterMap: ( f: (a: A) => Option -) => (fa: Readonly>) => Readonly> = (f) => filterMapWithIndex((_, a) => f(a)) +) => (fa: ReadonlyRecord) => ReadonlyRecord = (f) => filterMapWithIndex((_, a) => f(a)) /** * @category Filterable @@ -908,14 +1082,17 @@ export const filterMap: ( */ export const partition: { (refinement: Refinement): ( - fa: Readonly> - ) => Separated>, Readonly>> + fa: ReadonlyRecord + ) => Separated, ReadonlyRecord> + (predicate: Predicate): ( + fb: ReadonlyRecord + ) => Separated, ReadonlyRecord> (predicate: Predicate): ( - fa: Readonly> - ) => Separated>, Readonly>> + fa: ReadonlyRecord + ) => Separated, ReadonlyRecord> } = ( predicate: Predicate -): ((fa: Readonly>) => Separated>, Readonly>>) => +): ((fa: ReadonlyRecord) => Separated, ReadonlyRecord>) => partitionWithIndex((_, a) => predicate(a)) /** @@ -924,37 +1101,84 @@ export const partition: { */ export const partitionMap: ( f: (a: A) => Either -) => (fa: Readonly>) => Separated>, Readonly>> = (f) => +) => (fa: ReadonlyRecord) => Separated, ReadonlyRecord> = (f) => partitionMapWithIndex((_, a) => f(a)) /** * @category Foldable * @since 2.5.0 */ -export const reduce: (b: B, f: (b: B, a: A) => B) => (fa: Readonly>) => B = (b, f) => - reduceWithIndex(b, (_, b, a) => f(b, a)) +export function reduce(O: Ord): (b: B, f: (b: B, a: A) => B) => (fa: ReadonlyRecord) => B +/** + * Use the overload constrained by `Ord` instead. + * + * @deprecated + */ +export function reduce(b: B, f: (b: B, a: A) => B): (fa: ReadonlyRecord) => B +export function reduce( + ...args: [Ord] | [B, (b: B, a: A) => B] +): ((b: B, f: (b: B, a: A) => B) => (fa: ReadonlyRecord) => B) | ((fa: ReadonlyRecord) => B) { + if (args.length === 1) { + const reduceWithIndexO = reduceWithIndex(args[0]) + return (b: B, f: (b: B, a: A) => B) => reduceWithIndexO(b, (_, b, a) => f(b, a)) + } + return reduce(S.Ord)(...args) +} /** * @category Foldable * @since 2.5.0 */ -export const foldMap: (M: Monoid) => (f: (a: A) => M) => (fa: Readonly>) => M = (M) => { - const foldMapWithIndexM = foldMapWithIndex(M) - return (f) => foldMapWithIndexM((_, a) => f(a)) +export function foldMap( + O: Ord +): (M: Monoid) => (f: (a: A) => M) => (fa: ReadonlyRecord) => M +/** + * Use the overload constrained by `Ord` instead. + * + * @deprecated + */ +export function foldMap(M: Monoid): (f: (a: A) => M) => (fa: ReadonlyRecord) => M +export function foldMap( + O: Ord | Monoid +): + | ((M: Monoid) => (f: (a: A) => M) => (fa: ReadonlyRecord) => M) + | ((f: (a: A) => M) => (fa: ReadonlyRecord) => M) { + if ('compare' in O) { + const foldMapWithIndexO = foldMapWithIndex(O) + return (M: Monoid) => { + const foldMapWithIndexM = foldMapWithIndexO(M) + return (f: (a: A) => M): ((fa: ReadonlyRecord) => M) => foldMapWithIndexM((_, a) => f(a)) + } + } + return foldMap(S.Ord)(O) } /** * @category Foldable * @since 2.5.0 */ -export const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: Readonly>) => B = (b, f) => - reduceRightWithIndex(b, (_, a, b) => f(a, b)) +export function reduceRight(O: Ord): (b: B, f: (a: A, b: B) => B) => (fa: ReadonlyRecord) => B +/** + * Use the overload constrained by `Ord` instead. + * + * @deprecated + */ +export function reduceRight(b: B, f: (a: A, b: B) => B): (fa: ReadonlyRecord) => B +export function reduceRight( + ...args: [Ord] | [B, (a: A, b: B) => B] +): ((b: B, f: (a: A, b: B) => B) => (fa: ReadonlyRecord) => B) | ((fa: ReadonlyRecord) => B) { + if (args.length === 1) { + const reduceRightWithIndexO = reduceRightWithIndex(args[0]) + return (b: B, f: (a: A, b: B) => B) => reduceRightWithIndexO(b, (_, b, a) => f(b, a)) + } + return reduceRight(S.Ord)(...args) +} /** * @category Compactable * @since 2.5.0 */ -export const compact = (r: Readonly>>): Readonly> => { +export const compact = (r: ReadonlyRecord>): ReadonlyRecord => { const out: Record = {} for (const k in r) { if (_.has.call(r, k)) { @@ -972,8 +1196,8 @@ export const compact = (r: Readonly>>): Readonly( - r: Readonly>> -): Separated>, Readonly>> => { + r: ReadonlyRecord> +): Separated, ReadonlyRecord> => { const left: Record = {} const right: Record = {} for (const k in r) { @@ -1015,13 +1239,26 @@ declare module './HKT' { * @category instances * @since 2.5.0 */ -export function getShow(S: Show): Show> { - return { - show: (r) => { - const elements = collect((k, a: A) => `${JSON.stringify(k)}: ${S.show(a)}`)(r).join(', ') - return elements === '' ? '{}' : `{ ${elements} }` - } +export function getShow(O: Ord): (S: Show) => Show> +/** + * Use the overload constrained by `Ord` instead. + * + * @category instances + * @deprecated + */ +export function getShow(S: Show): Show> +export function getShow( + O: Ord | Show +): ((S: Show) => Show>) | Show> { + if ('compare' in O) { + return (S: Show) => ({ + show: (r: ReadonlyRecord) => { + const elements = collect(O)((k, a: A) => `${JSON.stringify(k)}: ${S.show(a)}`)(r).join(', ') + return elements === '' ? '{}' : `{ ${elements} }` + } + }) } + return getShow(S.Ord)(O) } /** @@ -1100,28 +1337,28 @@ export const FunctorWithIndex: FunctorWithIndex1 = { /** * @category instances - * @since 2.7.0 + * @since 2.11.0 */ -export const Foldable: Foldable1 = { +export const getFoldable = (O: Ord): Foldable1 => ({ URI, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight -} + reduce: _reduce(O), + foldMap: _foldMap(O), + reduceRight: _reduceRight(O) +}) /** * @category instances - * @since 2.7.0 + * @since 2.11.0 */ -export const FoldableWithIndex: FoldableWithIndex1 = { +export const getFoldableWithIndex = (O: Ord): FoldableWithIndex1 => ({ URI, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight, - reduceWithIndex: _reduceWithIndex, - foldMapWithIndex: _foldMapWithIndex, - reduceRightWithIndex: _reduceRightWithIndex -} + reduce: _reduce(O), + foldMap: _foldMap(O), + reduceRight: _reduceRight(O), + reduceWithIndex: _reduceWithIndex(O), + foldMapWithIndex: _foldMapWithIndex(O), + reduceRightWithIndex: _reduceRightWithIndex(O) +}) /** * @category instances @@ -1169,49 +1406,195 @@ export const FilterableWithIndex: FilterableWithIndex1 = { } /** + * @category instances + * @since 2.11.0 + */ +export const getTraversable = (O: Ord): Traversable1 => ({ + URI, + map: _map, + reduce: _reduce(O), + foldMap: _foldMap(O), + reduceRight: _reduceRight(O), + traverse: _traverse(O), + sequence: _sequence(O) +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const getTraversableWithIndex = (O: Ord): TraversableWithIndex1 => ({ + URI, + map: _map, + mapWithIndex: _mapWithIndex, + reduce: _reduce(O), + foldMap: _foldMap(O), + reduceRight: _reduceRight(O), + reduceWithIndex: _reduceWithIndex(O), + foldMapWithIndex: _foldMapWithIndex(O), + reduceRightWithIndex: _reduceRightWithIndex(O), + traverse: _traverse(O), + sequence: _sequence(O), + traverseWithIndex: _traverseWithIndex(O) +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const getWitherable = (O: Ord): Witherable1 => { + const T = getTraversable(O) + return { + URI, + map: _map, + reduce: _reduce(O), + foldMap: _foldMap(O), + reduceRight: _reduceRight(O), + traverse: T.traverse, + sequence: T.sequence, + compact, + separate, + filter: _filter, + filterMap: _filterMap, + partition: _partition, + partitionMap: _partitionMap, + wither: witherDefault(T, Compactable), + wilt: wiltDefault(T, Compactable) + } +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getUnionSemigroup = (S: Semigroup): Semigroup> => { + const unionS = union(S) + return { + concat: (first, second) => unionS(second)(first) + } +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getUnionMonoid = (S: Semigroup): Monoid> => ({ + concat: getUnionSemigroup(S).concat, + empty +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const getIntersectionSemigroup = (S: Semigroup): Semigroup> => { + const intersectionS = intersection(S) + return { + concat: (first, second) => intersectionS(second)(first) + } +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getDifferenceMagma = (): Magma> => ({ + concat: (first, second) => difference(second)(first) +}) + +// ------------------------------------------------------------------------------------- +// deprecated +// ------------------------------------------------------------------------------------- + +// tslint:disable: deprecation + +/** + * Use `getFoldable` instead. + * + * @category instances + * @since 2.7.0 + * @deprecated + */ +export const Foldable: Foldable1 = { + URI, + reduce: _reduce(S.Ord), + foldMap: _foldMap(S.Ord), + reduceRight: _reduceRight(S.Ord) +} + +/** + * Use `getFoldableWithIndex` instead. + * + * @category instances + * @since 2.7.0 + * @deprecated + */ +export const FoldableWithIndex: FoldableWithIndex1 = { + URI, + reduce: _reduce(S.Ord), + foldMap: _foldMap(S.Ord), + reduceRight: _reduceRight(S.Ord), + reduceWithIndex: _reduceWithIndex(S.Ord), + foldMapWithIndex: _foldMapWithIndex(S.Ord), + reduceRightWithIndex: _reduceRightWithIndex(S.Ord) +} + +/** + * Use `getTraversable` instead. + * * @category instances * @since 2.7.0 + * @deprecated */ export const Traversable: Traversable1 = { URI, map: _map, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight, - traverse: _traverse, + reduce: _reduce(S.Ord), + foldMap: _foldMap(S.Ord), + reduceRight: _reduceRight(S.Ord), + traverse: _traverse(S.Ord), sequence } /** + * Use `getTraversableWithIndex` instead. + * * @category instances * @since 2.7.0 + * @deprecated */ export const TraversableWithIndex: TraversableWithIndex1 = { URI, map: _map, mapWithIndex: _mapWithIndex, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight, - reduceWithIndex: _reduceWithIndex, - foldMapWithIndex: _foldMapWithIndex, - reduceRightWithIndex: _reduceRightWithIndex, - traverse: _traverse, + reduce: _reduce(S.Ord), + foldMap: _foldMap(S.Ord), + reduceRight: _reduceRight(S.Ord), + reduceWithIndex: _reduceWithIndex(S.Ord), + foldMapWithIndex: _foldMapWithIndex(S.Ord), + reduceRightWithIndex: _reduceRightWithIndex(S.Ord), + traverse: _traverse(S.Ord), sequence, - traverseWithIndex: _traverseWithIndex + traverseWithIndex: _traverseWithIndex(S.Ord) } +const _wither = witherDefault(Traversable, Compactable) +const _wilt = wiltDefault(Traversable, Compactable) + /** + * Use `getWitherable` instead. + * * @category instances * @since 2.7.0 + * @deprecated */ export const Witherable: Witherable1 = { URI, map: _map, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight, - traverse: _traverse, + reduce: _reduce(S.Ord), + foldMap: _foldMap(S.Ord), + reduceRight: _reduceRight(S.Ord), + traverse: _traverse(S.Ord), sequence, compact, separate, @@ -1223,10 +1606,6 @@ export const Witherable: Witherable1 = { wilt: _wilt } -// ------------------------------------------------------------------------------------- -// deprecated -// ------------------------------------------------------------------------------------- - /** * Use [`upsertAt`](#upsertat) instead. * @@ -1234,10 +1613,7 @@ export const Witherable: Witherable1 = { * @since 2.5.0 * @deprecated */ -export const insertAt: ( - k: string, - a: A -) => (r: Readonly>) => Readonly> = upsertAt +export const insertAt: (k: string, a: A) => (r: ReadonlyRecord) => ReadonlyRecord = upsertAt /** * Use [`has`](#has) instead. @@ -1264,10 +1640,10 @@ export const readonlyRecord: FunctorWithIndex1 & Witherable1 = { URI, map: _map, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight, - traverse: _traverse, + reduce: _reduce(S.Ord), + foldMap: _foldMap(S.Ord), + reduceRight: _reduceRight(S.Ord), + traverse: _traverse(S.Ord), sequence, compact, separate, @@ -1276,14 +1652,14 @@ export const readonlyRecord: FunctorWithIndex1 & partition: _partition, partitionMap: _partitionMap, mapWithIndex: _mapWithIndex, - reduceWithIndex: _reduceWithIndex, - foldMapWithIndex: _foldMapWithIndex, - reduceRightWithIndex: _reduceRightWithIndex, + reduceWithIndex: _reduceWithIndex(S.Ord), + foldMapWithIndex: _foldMapWithIndex(S.Ord), + reduceRightWithIndex: _reduceRightWithIndex(S.Ord), filterMapWithIndex: _filterMapWithIndex, filterWithIndex: _filterWithIndex, partitionMapWithIndex: _partitionMapWithIndex, partitionWithIndex: _partitionWithIndex, - traverseWithIndex: _traverseWithIndex, + traverseWithIndex: _traverseWithIndex(S.Ord), wither: _wither, wilt: _wilt } diff --git a/src/ReadonlySet.ts b/src/ReadonlySet.ts index 21d3cd003..256b4097d 100644 --- a/src/ReadonlySet.ts +++ b/src/ReadonlySet.ts @@ -2,54 +2,69 @@ * @since 2.5.0 */ import { Either } from './Either' +import { Eq, fromEquals } from './Eq' +import { identity } from './function' +import { Magma } from './Magma' import { Monoid } from './Monoid' +import { Option } from './Option' import { Ord } from './Ord' +import { not, Predicate } from './Predicate' +import { Refinement } from './Refinement' import { Semigroup } from './Semigroup' -import { Eq, fromEquals } from './Eq' -import { Predicate, not, Refinement, identity } from './function' import { Separated, separated } from './Separated' -import { Option } from './Option' import { Show } from './Show' +// ------------------------------------------------------------------------------------- +// interop +// ------------------------------------------------------------------------------------- + /** - * @category constructors + * @category interop * @since 2.5.0 */ -export function fromSet(s: Set): ReadonlySet { - return new Set(s) -} +export const fromSet = (s: Set): ReadonlySet => new Set(s) + +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- /** - * @category destructors + * Create a set with one element + * + * @category constructors * @since 2.5.0 */ -export function toSet(s: ReadonlySet): Set { - return new Set(s) -} +export const singleton = (a: A): ReadonlySet => new Set([a]) /** - * @category instances - * @since 2.5.0 + * Create a `ReadonlySet` from a `ReadonlyArray` + * + * @category constructors + * @since 2.10.0 */ -export function getShow(S: Show): Show> { - return { - show: (s) => { - const entries: Array = [] - s.forEach((a) => { - entries.push(S.show(a)) - }) - return `new Set([${entries.sort().join(', ')}])` +export const fromReadonlyArray = (E: Eq) => (as: ReadonlyArray): ReadonlySet => { + const len = as.length + const out = new Set() + const has = elem(E) + for (let i = 0; i < len; i++) { + const a = as[i] + if (!has(a, out)) { + out.add(a) } } + return out } +// ------------------------------------------------------------------------------------- +// destructors +// ------------------------------------------------------------------------------------- + /** - * @category instances + * @category destructors * @since 2.5.0 */ -export function getEq(E: Eq): Eq> { - const subsetE = isSubset(E) - return fromEquals((x, y) => subsetE(x, y) && subsetE(y, x)) +export function toSet(s: ReadonlySet): Set { + return new Set(s) } interface Next { @@ -101,17 +116,18 @@ export function chain(E: Eq): (f: (x: A) => ReadonlySet) => (set: Re * @since 2.5.0 */ export function filter(refinement: Refinement): (set: ReadonlySet) => ReadonlySet +export function filter(predicate: Predicate): (set: ReadonlySet) => ReadonlySet export function filter(predicate: Predicate): (set: ReadonlySet) => ReadonlySet export function filter(predicate: Predicate): (set: ReadonlySet) => ReadonlySet { - return (set) => { + return (set: ReadonlySet) => { const values = set.values() let e: Next const r = new Set() // tslint:disable-next-line: strict-boolean-expressions while (!(e = values.next()).done) { - const value = e.value - if (predicate(value)) { - r.add(value) + const a = e.value + if (predicate(a)) { + r.add(a) } } return r @@ -124,24 +140,27 @@ export function filter(predicate: Predicate): (set: ReadonlySet) => Rea export function partition( refinement: Refinement ): (set: ReadonlySet) => Separated, ReadonlySet> +export function partition( + predicate: Predicate +): (set: ReadonlySet) => Separated, ReadonlySet> export function partition( predicate: Predicate ): (set: ReadonlySet) => Separated, ReadonlySet> export function partition( predicate: Predicate ): (set: ReadonlySet) => Separated, ReadonlySet> { - return (set) => { + return (set: ReadonlySet) => { const values = set.values() let e: Next const right = new Set() const left = new Set() // tslint:disable-next-line: strict-boolean-expressions while (!(e = values.next()).done) { - const value = e.value - if (predicate(value)) { - right.add(value) + const a = e.value + if (predicate(a)) { + right.add(a) } else { - left.add(value) + left.add(a) } } return separated(left, right) @@ -288,27 +307,6 @@ export function difference( } } -/** - * @category instances - * @since 2.5.0 - */ -export function getUnionMonoid(E: Eq): Monoid> { - return { - concat: union(E), - empty - } -} - -/** - * @category instances - * @since 2.5.0 - */ -export function getIntersectionSemigroup(E: Eq): Semigroup> { - return { - concat: intersection(E) - } -} - /** * @since 2.5.0 */ @@ -326,12 +324,12 @@ export function foldMap(O: Ord, M: Monoid): (f: (a: A) => M) => (fa: } /** - * Create a set with one element - * - * @category constructors - * @since 2.5.0 + * @since 2.11.0 */ -export const singleton = (a: A): ReadonlySet => new Set([a]) +export const reduceRight = (O: Ord): ((b: B, f: (a: A, b: B) => B) => (fa: ReadonlySet) => B) => { + const toReadonlyArrayO = toReadonlyArray(O) + return (b, f) => (fa) => toReadonlyArrayO(fa).reduceRight((b, a) => f(a, b), b) +} /** * Insert a value into a set @@ -376,25 +374,6 @@ export const toggle = (E: Eq): ((a: A) => (set: ReadonlySet) => Readonl return (a) => (set) => (elemE(a, set) ? removeE : insertE)(a)(set) } -/** - * Create a set from an array - * - * @category constructors - * @since 2.10.0 - */ -export const fromReadonlyArray = (E: Eq) => (as: ReadonlyArray): ReadonlySet => { - const len = as.length - const out = new Set() - const has = elem(E) - for (let i = 0; i < len; i++) { - const a = as[i] - if (!has(a, out)) { - out.add(a) - } - } - return out -} - /** * @category combinators * @since 2.5.0 @@ -556,6 +535,86 @@ export const toReadonlyArray = (O: Ord) => (set: ReadonlySet): Readonly return out.sort(O.compare) } +// ------------------------------------------------------------------------------------- +// instances +// ------------------------------------------------------------------------------------- + +/** + * @category instances + * @since 2.11.0 + */ +export const URI = 'ReadonlySet' + +/** + * @category instances + * @since 2.11.0 + */ +export type URI = typeof URI + +declare module './HKT' { + interface URItoKind { + readonly [URI]: ReadonlySet + } +} + +/** + * @category instances + * @since 2.5.0 + */ +export function getShow(S: Show): Show> { + return { + show: (s) => { + const entries: Array = [] + s.forEach((a) => { + entries.push(S.show(a)) + }) + return `new Set([${entries.sort().join(', ')}])` + } + } +} + +/** + * @category instances + * @since 2.5.0 + */ +export function getEq(E: Eq): Eq> { + const subsetE = isSubset(E) + return fromEquals((x, y) => subsetE(x, y) && subsetE(y, x)) +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getUnionSemigroup = (E: Eq): Semigroup> => ({ + concat: union(E) +}) + +/** + * @category instances + * @since 2.5.0 + */ +export const getUnionMonoid = (E: Eq): Monoid> => ({ + concat: getUnionSemigroup(E).concat, + empty +}) + +/** + * @category instances + * @since 2.5.0 + */ +export const getIntersectionSemigroup = (E: Eq): Semigroup> => ({ + concat: intersection(E) +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const getDifferenceMagma = (E: Eq): Magma> => ({ + concat: difference(E) +}) + // ------------------------------------------------------------------------------------- // deprecated // ------------------------------------------------------------------------------------- diff --git a/src/Record.ts b/src/Record.ts index a305ce395..03efa8861 100644 --- a/src/Record.ts +++ b/src/Record.ts @@ -9,23 +9,26 @@ import { Filterable1 } from './Filterable' import { FilterableWithIndex1, PredicateWithIndex, RefinementWithIndex } from './FilterableWithIndex' import { Foldable as FoldableHKT, Foldable1, Foldable2, Foldable3 } from './Foldable' import { FoldableWithIndex1 } from './FoldableWithIndex' -import { pipe, Predicate, Refinement } from './function' +import { pipe } from './function' import { flap as flap_, Functor1 } from './Functor' import { FunctorWithIndex1 } from './FunctorWithIndex' import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT' +import * as _ from './internal' import { Magma } from './Magma' import { Monoid } from './Monoid' -import * as O from './Option' +import { Option } from './Option' +import { Ord } from './Ord' +import { Predicate } from './Predicate' import * as RR from './ReadonlyRecord' +import { Refinement } from './Refinement' import { Semigroup } from './Semigroup' import { Separated } from './Separated' import { Show } from './Show' +import * as S from './string' import { Traversable1 } from './Traversable' import { TraversableWithIndex1 } from './TraversableWithIndex' import { Unfoldable, Unfoldable1 } from './Unfoldable' -import { PipeableWilt1, PipeableWither1, Witherable1 } from './Witherable' - -import Option = O.Option +import { PipeableWilt1, PipeableWither1, wiltDefault, Witherable1, witherDefault } from './Witherable' // ------------------------------------------------------------------------------------- // model @@ -36,40 +39,63 @@ import Option = O.Option * * @since 2.0.0 */ -export const size: (r: Record) => number = RR.size +export const size: (r: Record) => number = RR.size /** * Test whether a `Record` is empty. * * @since 2.0.0 */ -export const isEmpty: (r: Record) => boolean = RR.isEmpty +export const isEmpty: (r: Record) => boolean = RR.isEmpty + +const keys_ = (O: Ord) => (r: Record): Array => + (Object.keys(r) as any).sort(O.compare) /** * @since 2.0.0 */ -export const keys: (r: Record) => Array = RR.keys as any +export const keys: (r: Record) => Array = + /*#__PURE__*/ + keys_(S.Ord) /** * Map a `Record` into an `Array`. * * @example * import { collect } from 'fp-ts/Record' + * import { Ord } from 'fp-ts/string' * * const x: { readonly a: string, readonly b: boolean } = { a: 'c', b: false } * assert.deepStrictEqual( - * collect((key, val) => ({ key: key, value: val }))(x), + * collect(Ord)((key, val) => ({ key: key, value: val }))(x), * [{ key: 'a', value: 'c' }, { key: 'b', value: false }] * ) * * @since 2.0.0 */ -export const collect = (f: (k: K, a: A) => B) => (r: Record): Array => { - const out: Array = [] - for (const key of keys(r)) { - out.push(f(key, r[key])) +export function collect(O: Ord): (f: (k: K, a: A) => B) => (r: Record) => Array +/** + * Use the overload constrained by `Ord` instead. + * + * @deprecated + */ +export function collect(f: (k: K, a: A) => B): (r: Record) => Array +export function collect( + O: Ord | ((k: string, a: A) => B) +): + | ((f: (k: K, a: A) => B) => (r: Record) => Array) + | ((r: Record) => Array) { + if (typeof O === 'function') { + return collect(S.Ord)(O) + } + const keysO = keys_(O) + return (f: (k: K, a: A) => B) => (r: Record) => { + const out: Array = [] + for (const key of keysO(r)) { + out.push(f(key, r[key])) + } + return out } - return out } /** @@ -79,7 +105,7 @@ export const collect = (f: (k: K, a: A) => B) => (r: Rec */ export const toArray: (r: Record) => Array<[K, A]> = /*#__PURE__*/ - collect((k, a) => [k, a]) + collect(S.Ord)((k, a) => [k, a]) /** * Unfolds a `Record` into a list of key/value pairs. @@ -94,7 +120,7 @@ export function toUnfoldable(U: Unfoldable): (r: Record) => return (r) => { const sas = toArray(r) const len = sas.length - return U.unfold(0, (b) => (b < len ? O.some([sas[b], b + 1]) : O.none)) + return U.unfold(0, (b) => (b < len ? _.some([sas[b], b + 1]) : _.none)) } } @@ -109,14 +135,12 @@ export const upsertAt: (k: string, a: A) => (r: Record) => Record< /** * Test whether or not a key exists in a `Record`. * - * Note. This function is not pipeable because is a custom type guard. + * Note. This function is not pipeable because is a `Refinement`. * * @since 2.10.0 */ export const has: (k: string, r: Record) => k is K = RR.has -const _hasOwnProperty = Object.prototype.hasOwnProperty - /** * Delete a key and value from a `Record`. * @@ -127,7 +151,7 @@ export function deleteAt( ): (r: Record) => Record, A> export function deleteAt(k: string): (r: Record) => Record { return (r: Record) => { - if (!_hasOwnProperty.call(r, k)) { + if (!_.has.call(r, k)) { return r } const out: Record = Object.assign({}, r) @@ -147,11 +171,11 @@ export const updateAt = (k: string, a: A): ((r: Record(k: string, f: (a: A) => A) => (r: Record): Option> => { if (!has(k, r)) { - return O.none + return _.none } const out: Record = Object.assign({}, r) out[k] = f(r[k]) - return O.some(out) + return _.some(out) } /** @@ -166,7 +190,7 @@ export function pop(k: string): (r: Record) => Option<[A, Record { const oa = lookup(k, r) - return O.isNone(oa) ? O.none : O.some([oa.value, deleteAtk(r)]) + return _.isNone(oa) ? _.none : _.some([oa.value, deleteAtk(r)]) } } @@ -212,23 +236,60 @@ export const map: (f: (a: A) => B) => (fa: Record) /** * @since 2.0.0 */ -export const reduceWithIndex: (b: B, f: (k: K, b: B, a: A) => B) => (fa: Record) => B = - RR.reduceWithIndex +export function reduceWithIndex( + O: Ord +): (b: B, f: (k: K, b: B, a: A) => B) => (fa: Record) => B +/** + * Use the overload constrained by `Ord` instead. + * + * @deprecated + */ +export function reduceWithIndex(b: B, f: (k: K, b: B, a: A) => B): (fa: Record) => B +export function reduceWithIndex( + ...args: [Ord] | [B, (k: string, b: B, a: A) => B] +): ((b: B, f: (k: string, b: B, a: A) => B) => (fa: Record) => B) | ((fa: Record) => B) { + return args.length === 1 ? RR.reduceWithIndex(args[0]) : RR.reduceWithIndex(S.Ord)(...args) +} /** * @since 2.0.0 */ -export const foldMapWithIndex: ( +export function foldMapWithIndex( + O: Ord +): (M: Monoid) => (f: (k: K, a: A) => M) => (fa: Record) => M +/** + * Use the overload constrained by `Ord` instead. + * + * @deprecated + */ +export function foldMapWithIndex( M: Monoid -) => (f: (k: K, a: A) => M) => (fa: Record) => M = RR.foldMapWithIndex +): (f: (k: K, a: A) => M) => (fa: Record) => M +export function foldMapWithIndex( + O: Ord | Monoid +): + | ((M: Monoid) => (f: (k: string, a: A) => M) => (fa: Record) => M) + | ((f: (k: string, a: A) => M) => (fa: Record) => M) { + return 'compare' in O ? RR.foldMapWithIndex(O) : RR.foldMapWithIndex(S.Ord)(O) +} /** * @since 2.0.0 */ -export const reduceRightWithIndex: ( - b: B, - f: (k: K, a: A, b: B) => B -) => (fa: Record) => B = RR.reduceRightWithIndex +export function reduceRightWithIndex( + O: Ord +): (b: B, f: (k: K, a: A, b: B) => B) => (fa: Record) => B +/** + * Use the overload constrained by `Ord` instead. + * + * @deprecated + */ +export function reduceRightWithIndex(b: B, f: (k: K, a: A, b: B) => B): (fa: Record) => B +export function reduceRightWithIndex( + ...args: [Ord] | [B, (k: string, a: A, b: B) => B] +): ((b: B, f: (k: string, a: A, b: B) => B) => (fa: Record) => B) | ((fa: Record) => B) { + return args.length === 1 ? RR.reduceRightWithIndex(args[0]) : RR.reduceRightWithIndex(S.Ord)(...args) +} /** * Create a `Record` with one key/value pair. @@ -355,6 +416,9 @@ export const partitionMapWithIndex: ( export function partitionWithIndex( refinementWithIndex: RefinementWithIndex ): (fa: Record) => Separated, Record> +export function partitionWithIndex( + predicateWithIndex: PredicateWithIndex +): (fb: Record) => Separated, Record> export function partitionWithIndex( predicateWithIndex: PredicateWithIndex ): (fa: Record) => Separated, Record> @@ -368,7 +432,7 @@ export function partitionWithIndex( * @since 2.0.0 */ export const filterMapWithIndex: ( - f: (key: K, a: A) => O.Option + f: (key: K, a: A) => Option ) => (fa: Record) => Record = RR.filterMapWithIndex /** @@ -377,6 +441,9 @@ export const filterMapWithIndex: ( export function filterWithIndex( refinementWithIndex: RefinementWithIndex ): (fa: Record) => Record +export function filterWithIndex( + predicateWithIndex: PredicateWithIndex +): (fb: Record) => Record export function filterWithIndex( predicateWithIndex: PredicateWithIndex ): (fa: Record) => Record @@ -488,89 +555,95 @@ export const elem: ( (a: A, fa: Record): boolean } = RR.elem +/** + * @category combinators + * @since 2.11.0 + */ +export const union = ( + M: Magma +): ((second: Record) => (first: Record) => Record) => { + const unionM = RR.union(M) + return (second) => (first) => { + if (isEmpty(first)) { + return { ...second } + } + if (isEmpty(second)) { + return { ...first } + } + return unionM(second)(first) + } +} + +/** + * @category combinators + * @since 2.11.0 + */ +export const intersection = (M: Magma) => (second: Record) => ( + first: Record +): Record => { + if (isEmpty(first) || isEmpty(second)) { + return {} + } + return RR.intersection(M)(second)(first) +} + +/** + * @category combinators + * @since 2.11.0 + */ +export const difference = (second: Record) => (first: Record): Record => { + if (isEmpty(first)) { + return { ...second } + } + if (isEmpty(second)) { + return { ...first } + } + return RR.difference(second)(first) +} + // ------------------------------------------------------------------------------------- // non-pipeables // ------------------------------------------------------------------------------------- -/* istanbul ignore next */ -const _map: Functor1['map'] = (fa, f) => pipe(fa, map(f)) -/* istanbul ignore next */ -const _mapWithIndex: FunctorWithIndex1['mapWithIndex'] = (fa, f) => pipe(fa, mapWithIndex(f)) -/* istanbul ignore next */ -const _reduce: Foldable1['reduce'] = (fa, b, f) => pipe(fa, reduce(b, f)) -/* istanbul ignore next */ -const _foldMap: Foldable1['foldMap'] = (M) => { - const foldMapM = foldMap(M) - return (fa, f) => pipe(fa, foldMapM(f)) -} -/* istanbul ignore next */ -const _reduceRight: Foldable1['reduceRight'] = (fa, b, f) => pipe(fa, reduceRight(b, f)) -/* istanbul ignore next */ -const _traverse = ( - F: Applicative -): ((ta: Record, f: (a: A) => HKT) => HKT>) => { - const traverseF = traverse(F) - return (ta, f) => pipe(ta, traverseF(f)) -} -/* istanbul ignore next */ -const _filter = (fa: Record, predicate: Predicate): Record => pipe(fa, filter(predicate)) -/* istanbul ignore next */ -const _filterMap: Filterable1['filterMap'] = (fa, f) => pipe(fa, filterMap(f)) -/* istanbul ignore next */ -const _partition = ( - fa: Record, - predicate: Predicate -): Separated, Record> => pipe(fa, partition(predicate)) -/* istanbul ignore next */ -const _partitionMap: Filterable1['partitionMap'] = (fa, f) => pipe(fa, partitionMap(f)) -/* istanbul ignore next */ -const _reduceWithIndex: FoldableWithIndex1['reduceWithIndex'] = (fa, b, f) => - pipe(fa, reduceWithIndex(b, f)) -/* istanbul ignore next */ -const _foldMapWithIndex: FoldableWithIndex1['foldMapWithIndex'] = (M) => { - const foldMapWithIndexM = foldMapWithIndex(M) - return (fa, f) => pipe(fa, foldMapWithIndexM(f)) -} -/* istanbul ignore next */ -const _reduceRightWithIndex: FoldableWithIndex1['reduceRightWithIndex'] = (fa, b, f) => - pipe(fa, reduceRightWithIndex(b, f)) -/* istanbul ignore next */ -const _partitionMapWithIndex = ( - fa: Record, - f: (key: string, a: A) => Either -): Separated, Record> => pipe(fa, partitionMapWithIndex(f)) -/* istanbul ignore next */ -const _partitionWithIndex = (fa: Record, predicateWithIndex: PredicateWithIndex) => - pipe(fa, partitionWithIndex(predicateWithIndex)) -/* istanbul ignore next */ -const _filterMapWithIndex = (fa: Record, f: (key: string, a: A) => Option) => - pipe(fa, filterMapWithIndex(f)) -/* istanbul ignore next */ -const _filterWithIndex = (fa: Record, predicateWithIndex: PredicateWithIndex) => - pipe(fa, filterWithIndex(predicateWithIndex)) -/* istanbul ignore next */ -const _traverseWithIndex = ( +const _map = RR._map +const _mapWithIndex = RR._mapWithIndex +const _reduce = RR._reduce +const _foldMap = RR._foldMap +const _reduceRight = RR._reduceRight +const _filter = RR._filter +const _filterMap = RR._filterMap +const _partition = RR._partition +const _partitionMap = RR._partitionMap +const _reduceWithIndex = RR._reduceWithIndex +const _foldMapWithIndex = RR._foldMapWithIndex +const _reduceRightWithIndex = RR._reduceRightWithIndex +const _partitionMapWithIndex = RR._partitionMapWithIndex +const _partitionWithIndex = RR._partitionWithIndex +const _filterMapWithIndex = RR._filterMapWithIndex +const _filterWithIndex = RR._filterWithIndex +const _traverse = RR._traverse +const _sequence = RR._sequence +const _traverseWithIndex = (O: Ord) => ( F: Applicative ): ((ta: Record, f: (k: string, a: A) => HKT) => HKT>) => { - const traverseWithIndexF = traverseWithIndex(F) - return (ta, f) => pipe(ta, traverseWithIndexF(f)) -} -/* istanbul ignore next */ -const _wither = ( - F: Applicative -): ((fa: Record, f: (a: A) => HKT>) => HKT>) => { - const witherF = wither(F) - return (fa, f) => pipe(fa, witherF(f)) -} -/* istanbul ignore next */ -const _wilt = ( - F: Applicative -): (( - fa: Record, - f: (a: A) => HKT> -) => HKT, Record>>) => { - const wiltF = wilt(F) - return (fa, f) => pipe(fa, wiltF(f)) + const keysO = keys_(O) + return (ta: Record, f: (k: string, a: A) => HKT) => { + const ks = keysO(ta) + if (ks.length === 0) { + return F.of({}) + } + let fr: HKT> = F.of({}) + for (const key of ks) { + fr = F.ap( + F.map(fr, (r) => (b: B) => { + r[key] = b + return r + }), + f(key, ta[key]) + ) + } + return fr + } } // ------------------------------------------------------------------------------------- @@ -583,6 +656,7 @@ const _wilt = ( */ export const filter: { (refinement: Refinement): (fa: Record) => Record + (predicate: Predicate): (fb: Record) => Record (predicate: Predicate): (fa: Record) => Record } = RR.filter @@ -592,12 +666,6 @@ export const filter: { */ export const filterMap: (f: (a: A) => Option) => (fa: Record) => Record = RR.filterMap -/** - * @category Foldable - * @since 2.0.0 - */ -export const foldMap: (M: Monoid) => (f: (a: A) => M) => (fa: Record) => M = RR.foldMap - /** * @category Filterable * @since 2.0.0 @@ -606,6 +674,7 @@ export const partition: { (refinement: Refinement): ( fa: Record ) => Separated, Record> + (predicate: Predicate): (fb: Record) => Separated, Record> (predicate: Predicate): (fa: Record) => Separated, Record> } = RR.partition @@ -621,13 +690,54 @@ export const partitionMap: ( * @category Foldable * @since 2.0.0 */ -export const reduce: (b: B, f: (b: B, a: A) => B) => (fa: Record) => B = RR.reduce +export function reduce(O: Ord): (b: B, f: (b: B, a: A) => B) => (fa: Record) => B +/** + * Use the overload constrained by `Ord` instead. + * + * @deprecated + */ +export function reduce(b: B, f: (b: B, a: A) => B): (fa: Record) => B +export function reduce( + ...args: [Ord] | [B, (b: B, a: A) => B] +): ((b: B, f: (b: B, a: A) => B) => (fa: Record) => B) | ((fa: Record) => B) { + return args.length === 1 ? RR.reduce(args[0]) : RR.reduce(S.Ord)(...args) +} /** * @category Foldable * @since 2.0.0 */ -export const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: Record) => B = RR.reduceRight +export function foldMap(O: Ord): (M: Monoid) => (f: (a: A) => M) => (fa: Record) => M +/** + * Use the overload constrained by `Ord` instead. + * + * @deprecated + */ +export function foldMap(M: Monoid): (f: (a: A) => M) => (fa: Record) => M +export function foldMap( + O: Ord | Monoid +): + | ((M: Monoid) => (f: (a: A) => M) => (fa: Record) => M) + | ((f: (a: A) => M) => (fa: Record) => M) { + return 'compare' in O ? RR.foldMap(O) : RR.foldMap(S.Ord)(O) +} + +/** + * @category Foldable + * @since 2.0.0 + */ +export function reduceRight(O: Ord): (b: B, f: (a: A, b: B) => B) => (fa: Record) => B +/** + * Use the overload constrained by `Ord` instead. + * + * @deprecated + */ +export function reduceRight(b: B, f: (a: A, b: B) => B): (fa: Record) => B +export function reduceRight( + ...args: [Ord] | [B, (a: A, b: B) => B] +): ((b: B, f: (a: A, b: B) => B) => (fa: Record) => B) | ((fa: Record) => B) { + return args.length === 1 ? RR.reduceRight(args[0]) : RR.reduceRight(S.Ord)(...args) +} /** * @category Compactable @@ -668,7 +778,19 @@ declare module './HKT' { * @category instances * @since 2.0.0 */ -export const getShow: (S: Show) => Show> = RR.getShow +export function getShow(O: Ord): (S: Show) => Show> +/** + * Use the overload constrained by `Ord` instead. + * + * @category instances + * @deprecated + */ +export function getShow(S: Show): Show> +export function getShow( + O: Ord | Show +): ((S: Show) => Show>) | Show> { + return 'compare' in O ? RR.getShow(O) : RR.getShow(S.Ord)(O) +} /** * @category instances @@ -722,28 +844,28 @@ export const FunctorWithIndex: FunctorWithIndex1 = { /** * @category instances - * @since 2.7.0 + * @since 2.11.0 */ -export const Foldable: Foldable1 = { +export const getFoldable = (O: Ord): Foldable1 => ({ URI, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight -} + reduce: _reduce(O), + foldMap: _foldMap(O), + reduceRight: _reduceRight(O) +}) /** * @category instances - * @since 2.7.0 + * @since 2.11.0 */ -export const FoldableWithIndex: FoldableWithIndex1 = { +export const getFoldableWithIndex = (O: Ord): FoldableWithIndex1 => ({ URI, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight, - reduceWithIndex: _reduceWithIndex, - foldMapWithIndex: _foldMapWithIndex, - reduceRightWithIndex: _reduceRightWithIndex -} + reduce: _reduce(O), + foldMap: _foldMap(O), + reduceRight: _reduceRight(O), + reduceWithIndex: _reduceWithIndex(O), + foldMapWithIndex: _foldMapWithIndex(O), + reduceRightWithIndex: _reduceRightWithIndex(O) +}) /** * @category instances @@ -791,49 +913,195 @@ export const FilterableWithIndex: FilterableWithIndex1 = { } /** + * @category instances + * @since 2.11.0 + */ +export const getTraversable = (O: Ord): Traversable1 => ({ + URI, + map: _map, + reduce: _reduce(O), + foldMap: _foldMap(O), + reduceRight: _reduceRight(O), + traverse: _traverse(O), + sequence: _sequence(O) +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const getTraversableWithIndex = (O: Ord): TraversableWithIndex1 => ({ + URI, + map: _map, + mapWithIndex: _mapWithIndex, + reduce: _reduce(O), + foldMap: _foldMap(O), + reduceRight: _reduceRight(O), + reduceWithIndex: _reduceWithIndex(O), + foldMapWithIndex: _foldMapWithIndex(O), + reduceRightWithIndex: _reduceRightWithIndex(O), + traverse: _traverse(O), + sequence: _sequence(O), + traverseWithIndex: _traverseWithIndex(O) +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const getWitherable = (O: Ord): Witherable1 => { + const T = getTraversable(O) + return { + URI, + map: _map, + reduce: _reduce(O), + foldMap: _foldMap(O), + reduceRight: _reduceRight(O), + traverse: T.traverse, + sequence: T.sequence, + compact, + separate, + filter: _filter, + filterMap: _filterMap, + partition: _partition, + partitionMap: _partitionMap, + wither: witherDefault(T, Compactable), + wilt: wiltDefault(T, Compactable) + } +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getUnionSemigroup = (S: Semigroup): Semigroup> => { + const unionS = union(S) + return { + concat: (first, second) => unionS(second)(first) + } +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getUnionMonoid = (S: Semigroup): Monoid> => ({ + concat: getUnionSemigroup(S).concat, + empty: {} +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const getIntersectionSemigroup = (S: Semigroup): Semigroup> => { + const intersectionS = intersection(S) + return { + concat: (first, second) => intersectionS(second)(first) + } +} + +/** + * @category instances + * @since 2.11.0 + */ +export const getDifferenceMagma = (): Magma> => ({ + concat: (first, second) => difference(second)(first) +}) + +// ------------------------------------------------------------------------------------- +// deprecated +// ------------------------------------------------------------------------------------- + +// tslint:disable: deprecation + +/** + * Use `getFoldable` instead. + * * @category instances * @since 2.7.0 + * @deprecated + */ +export const Foldable: Foldable1 = { + URI, + reduce: _reduce(S.Ord), + foldMap: _foldMap(S.Ord), + reduceRight: _reduceRight(S.Ord) +} + +/** + * Use `getFoldableWithIndex` instead. + * + * @category instances + * @since 2.7.0 + * @deprecated + */ +export const FoldableWithIndex: FoldableWithIndex1 = { + URI, + reduce: _reduce(S.Ord), + foldMap: _foldMap(S.Ord), + reduceRight: _reduceRight(S.Ord), + reduceWithIndex: _reduceWithIndex(S.Ord), + foldMapWithIndex: _foldMapWithIndex(S.Ord), + reduceRightWithIndex: _reduceRightWithIndex(S.Ord) +} + +/** + * Use `getTraversable` instead. + * + * @category instances + * @since 2.7.0 + * @deprecated */ export const Traversable: Traversable1 = { URI, map: _map, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight, - traverse: _traverse, + reduce: _reduce(S.Ord), + foldMap: _foldMap(S.Ord), + reduceRight: _reduceRight(S.Ord), + traverse: _traverse(S.Ord), sequence } /** + * Use the `getTraversableWithIndex` instead. + * * @category instances * @since 2.7.0 + * @deprecated */ export const TraversableWithIndex: TraversableWithIndex1 = { URI, map: _map, mapWithIndex: _mapWithIndex, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight, - reduceWithIndex: _reduceWithIndex, - foldMapWithIndex: _foldMapWithIndex, - reduceRightWithIndex: _reduceRightWithIndex, - traverse: _traverse, + reduce: _reduce(S.Ord), + foldMap: _foldMap(S.Ord), + reduceRight: _reduceRight(S.Ord), + reduceWithIndex: _reduceWithIndex(S.Ord), + foldMapWithIndex: _foldMapWithIndex(S.Ord), + reduceRightWithIndex: _reduceRightWithIndex(S.Ord), + traverse: _traverse(S.Ord), sequence, - traverseWithIndex: _traverseWithIndex + traverseWithIndex: _traverseWithIndex(S.Ord) } +const _wither = witherDefault(Traversable, Compactable) +const _wilt = wiltDefault(Traversable, Compactable) + /** + * Use `getWitherable` instead. + * * @category instances * @since 2.7.0 + * @deprecated */ export const Witherable: Witherable1 = { URI, map: _map, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight, - traverse: _traverse, + reduce: _reduce(S.Ord), + foldMap: _foldMap(S.Ord), + reduceRight: _reduceRight(S.Ord), + traverse: _traverse(S.Ord), sequence, compact, separate, @@ -845,10 +1113,6 @@ export const Witherable: Witherable1 = { wilt: _wilt } -// ------------------------------------------------------------------------------------- -// deprecated -// ------------------------------------------------------------------------------------- - /** * Use a new `{}` instead. * @@ -871,7 +1135,6 @@ export const insertAt: (k: string, a: A) => (r: Record) => Record< * @since 2.0.0 * @deprecated */ -// tslint:disable-next-line: deprecation export const hasOwnProperty: (k: string, r: Record) => k is K = RR.hasOwnProperty /** @@ -888,10 +1151,10 @@ export const record: FunctorWithIndex1 & Witherable1 = { URI, map: _map, - reduce: _reduce, - foldMap: _foldMap, - reduceRight: _reduceRight, - traverse: _traverse, + reduce: _reduce(S.Ord), + foldMap: _foldMap(S.Ord), + reduceRight: _reduceRight(S.Ord), + traverse: _traverse(S.Ord), sequence, compact, separate, @@ -900,14 +1163,14 @@ export const record: FunctorWithIndex1 & partition: _partition, partitionMap: _partitionMap, mapWithIndex: _mapWithIndex, - reduceWithIndex: _reduceWithIndex, - foldMapWithIndex: _foldMapWithIndex, - reduceRightWithIndex: _reduceRightWithIndex, + reduceWithIndex: _reduceWithIndex(S.Ord), + foldMapWithIndex: _foldMapWithIndex(S.Ord), + reduceRightWithIndex: _reduceRightWithIndex(S.Ord), filterMapWithIndex: _filterMapWithIndex, filterWithIndex: _filterWithIndex, partitionMapWithIndex: _partitionMapWithIndex, partitionWithIndex: _partitionWithIndex, - traverseWithIndex: _traverseWithIndex, + traverseWithIndex: _traverseWithIndex(S.Ord), wither: _wither, wilt: _wilt } diff --git a/src/Refinement.ts b/src/Refinement.ts new file mode 100644 index 000000000..96f25f11f --- /dev/null +++ b/src/Refinement.ts @@ -0,0 +1,94 @@ +/** + * @since 2.11.0 + */ +import { Option } from './Option' +import * as _ from './internal' +import { Either } from './Either' + +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export interface Refinement { + (a: A): a is B +} + +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- + +/** + * Returns a `Refinement` from a `Option` returning function. + * This function ensures that a `Refinement` definition is type-safe. + * + * @category constructors + * @since 2.11.0 + */ +export const fromOptionK = (getOption: (a: A) => Option): Refinement => { + return (a: A): a is B => _.isSome(getOption(a)) +} + +/** + * @category constructors + * @since 2.11.0 + */ +export const fromEitherK = (getEither: (a: A) => Either): Refinement => { + return (a: A): a is B => _.isRight(getEither(a)) +} + +/** + * @category constructors + * @since 2.11.0 + */ +export const id = (): Refinement => { + return (_): _ is A => true +} + +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- + +/** + * @category combinators + * @since 2.11.0 + */ +export const not = (refinement: Refinement): Refinement> => ( + a +): a is Exclude => !refinement(a) + +/** + * @category combinators + * @since 2.11.0 + */ +export const or = (second: Refinement) => ( + first: Refinement +): Refinement => (a): a is B | C => first(a) || second(a) + +/** + * @category combinators + * @since 2.11.0 + */ +export const and = (second: Refinement) => ( + first: Refinement +): Refinement => (a): a is B & C => first(a) && second(a) + +/** + * @category combinators + * @since 2.11.0 + */ +export const zero = (): Refinement => { + return (_): _ is B => false +} + +/** + * @category combinators + * @since 2.11.0 + */ +export const compose = (bc: Refinement) => ( + ab: Refinement +): Refinement => { + return (i): i is C => ab(i) && bc(i) +} diff --git a/src/Semigroup.ts b/src/Semigroup.ts index fbba94f51..a79444433 100644 --- a/src/Semigroup.ts +++ b/src/Semigroup.ts @@ -39,11 +39,12 @@ */ import { getSemigroup, identity } from './function' import * as _ from './internal' -import { Magma } from './Magma' +import * as M from './Magma' import * as Or from './Ord' import { ReadonlyRecord } from './ReadonlyRecord' import Ord = Or.Ord +import Magma = M.Magma // ------------------------------------------------------------------------------------- // model @@ -119,9 +120,7 @@ export const constant = (a: A): Semigroup => ({ * @category combinators * @since 2.10.0 */ -export const reverse = (S: Semigroup): Semigroup => ({ - concat: (x, y) => S.concat(y, x) -}) +export const reverse: (S: Semigroup) => Semigroup = M.reverse /** * Given a struct of semigroups returns a semigroup for the struct. @@ -232,12 +231,6 @@ export const first = (): Semigroup => ({ concat: identity }) */ export const last = (): Semigroup => ({ concat: (_, y) => y }) -/** - * @category instances - * @since 2.0.0 - */ -export const semigroupVoid: Semigroup = constant(undefined) - // ------------------------------------------------------------------------------------- // utils // ------------------------------------------------------------------------------------- @@ -258,13 +251,21 @@ export const semigroupVoid: Semigroup = constant(undefined) * * @since 2.10.0 */ -export const concatAll = (S: Semigroup) => (startWith: A) => (as: ReadonlyArray): A => - as.reduce(S.concat, startWith) +export const concatAll: (S: Semigroup) => (startWith: A) => (as: ReadonlyArray) => A = M.concatAll // ------------------------------------------------------------------------------------- // deprecated // ------------------------------------------------------------------------------------- +/** + * Use `void` module instead. + * + * @category instances + * @since 2.0.0 + * @deprecated + */ +export const semigroupVoid: Semigroup = constant(undefined) + /** * Use [`getAssignSemigroup`](./struct.ts.html#getAssignSemigroup) instead. * diff --git a/src/Set.ts b/src/Set.ts index 98c199bc8..9b5179f71 100644 --- a/src/Set.ts +++ b/src/Set.ts @@ -1,15 +1,18 @@ /** * @since 2.0.0 */ -import { separated, Separated } from './Separated' import { Either } from './Either' import { Eq } from './Eq' -import { identity, Predicate, Refinement } from './function' +import { identity } from './function' +import { Magma } from './Magma' import { Monoid } from './Monoid' import { Option } from './Option' import { Ord } from './Ord' +import { Predicate } from './Predicate' import * as RS from './ReadonlySet' +import { Refinement } from './Refinement' import { Semigroup } from './Semigroup' +import { separated, Separated } from './Separated' import { Show } from './Show' /** @@ -76,17 +79,18 @@ interface Next { * @since 2.0.0 */ export function filter(refinement: Refinement): (set: Set) => Set +export function filter(predicate: Predicate): (set: Set) => Set export function filter(predicate: Predicate): (set: Set) => Set export function filter(predicate: Predicate): (set: Set) => Set { - return (set) => { + return (set: Set) => { const values = set.values() let e: Next const r = new Set() // tslint:disable-next-line: strict-boolean-expressions while (!(e = values.next()).done) { - const value = e.value - if (predicate(value)) { - r.add(value) + const a = e.value + if (predicate(a)) { + r.add(a) } } return r @@ -97,20 +101,21 @@ export function filter(predicate: Predicate): (set: Set) => Set { * @since 2.0.0 */ export function partition(refinement: Refinement): (set: Set) => Separated, Set> +export function partition(predicate: Predicate): (set: Set) => Separated, Set> export function partition(predicate: Predicate): (set: Set) => Separated, Set> export function partition(predicate: Predicate): (set: Set) => Separated, Set> { - return (set) => { + return (set: Set) => { const values = set.values() let e: Next const right = new Set() const left = new Set() // tslint:disable-next-line: strict-boolean-expressions while (!(e = values.next()).done) { - const value = e.value - if (predicate(value)) { - right.add(value) + const a = e.value + if (predicate(a)) { + right.add(a) } else { - left.add(value) + left.add(a) } } return separated(left, right) @@ -251,26 +256,38 @@ export function difference(E: Eq): (me: Set, that?: Set) => Set | } } +/** + * @category instances + * @since 2.11.0 + */ +export const getUnionSemigroup = (E: Eq): Semigroup> => ({ + concat: union(E) +}) + /** * @category instances * @since 2.0.0 */ -export function getUnionMonoid(E: Eq): Monoid> { - return { - concat: union(E), - empty: new Set() - } -} +export const getUnionMonoid = (E: Eq): Monoid> => ({ + concat: getUnionSemigroup(E).concat, + empty: new Set() +}) /** * @category instances * @since 2.0.0 */ -export function getIntersectionSemigroup(E: Eq): Semigroup> { - return { - concat: intersection(E) - } -} +export const getIntersectionSemigroup = (E: Eq): Semigroup> => ({ + concat: intersection(E) +}) + +/** + * @category instances + * @since 2.11.0 + */ +export const getDifferenceMagma = (E: Eq): Magma> => ({ + concat: difference(E) +}) /** * @since 2.0.0 @@ -282,6 +299,11 @@ export const reduce: (O: Ord) => (b: B, f: (b: B, a: A) => B) => (fa: S */ export const foldMap: (O: Ord, M: Monoid) => (f: (a: A) => M) => (fa: Set) => M = RS.foldMap +/** + * @since 2.11.0 + */ +export const reduceRight: (O: Ord) => (b: B, f: (a: A, b: B) => B) => (fa: Set) => B = RS.reduceRight + /** * Create a set with one element * diff --git a/src/State.ts b/src/State.ts index f5c122eac..f3477a4ae 100644 --- a/src/State.ts +++ b/src/State.ts @@ -2,12 +2,16 @@ * @since 2.0.0 */ import { Applicative2 } from './Applicative' -import { apFirst as apFirst_, Apply2, apSecond as apSecond_, apS as apS_ } from './Apply' +import { apFirst as apFirst_, Apply2, apS as apS_, apSecond as apSecond_ } from './Apply' +import { bind as bind_, Chain2, chainFirst as chainFirst_ } from './Chain' +import { FromState2 } from './FromState' import { identity, pipe } from './function' import { bindTo as bindTo_, flap as flap_, Functor2 } from './Functor' -import { bind as bind_, Chain2, chainFirst as chainFirst_ } from './Chain' -import { Pointed2 } from './Pointed' import { Monad2 } from './Monad' +import { NonEmptyArray } from './NonEmptyArray' +import { Pointed2 } from './Pointed' +import { ReadonlyNonEmptyArray } from './ReadonlyNonEmptyArray' +import * as _ from './internal' // ------------------------------------------------------------------------------------- // model @@ -254,6 +258,14 @@ export const chainFirst: (f: (a: A) => State) => (ma: State /*#__PURE__*/ chainFirst_(Chain) +/** + * @category instances + * @since 2.11.0 + */ +export const FromState: FromState2 = { + URI, + fromState: identity +} // ------------------------------------------------------------------------------------- // utils // ------------------------------------------------------------------------------------- @@ -306,35 +318,51 @@ export const apS = // ------------------------------------------------------------------------------------- /** - * Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. * - * @since 2.9.0 - */ -export const traverseArrayWithIndex = (f: (index: number, a: A) => State) => ( - as: ReadonlyArray -): State> => (s) => { - let lastState = s - const values = [] - for (let i = 0; i < as.length; i++) { - const [newValue, newState] = f(i, as[i])(lastState) - values.push(newValue) - lastState = newState + * @since 2.11.0 + */ +export const traverseReadonlyNonEmptyArrayWithIndex = (f: (index: number, a: A) => State) => ( + as: ReadonlyNonEmptyArray +): State> => (s) => { + const [b, s2] = f(0, _.head(as))(s) + const bs: NonEmptyArray = [b] + let out = s2 + for (let i = 1; i < as.length; i++) { + const [b, s2] = f(i, as[i])(out) + bs.push(b) + out = s2 } - return [values, lastState] + return [bs, out] } /** - * Equivalent to `ReadonlyArray#traverse(Applicative)`. + * Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndex = ( + f: (index: number, a: A) => State +): ((as: ReadonlyArray) => State>) => { + const g = traverseReadonlyNonEmptyArrayWithIndex(f) + return (as) => (_.isNonEmpty(as) ? g(as) : of(_.emptyReadonlyArray)) +} + +/** + * @since 2.9.0 + */ +export const traverseArrayWithIndex: ( + f: (index: number, a: A) => State +) => (as: ReadonlyArray) => State> = traverseReadonlyArrayWithIndex + +/** * @since 2.9.0 */ export const traverseArray = ( f: (a: A) => State -): ((as: ReadonlyArray) => State>) => traverseArrayWithIndex((_, a) => f(a)) +): ((as: ReadonlyArray) => State>) => traverseReadonlyArrayWithIndex((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(Applicative)`. - * * @since 2.9.0 */ export const sequenceArray: (arr: ReadonlyArray>) => State> = @@ -345,6 +373,8 @@ export const sequenceArray: (arr: ReadonlyArray>) => State(me: Task): StateReaderTa return fromReaderTaskEither(RTE.leftTask(me)) } -/** - * @category constructors - * @since 2.0.0 - */ -export function fromTaskEither(ma: TaskEither): StateReaderTaskEither { - return fromReaderTaskEither(RTE.fromTaskEither(ma)) -} - /** * @category constructors * @since 2.0.0 @@ -115,22 +132,6 @@ export function leftReader(me: Reader): StateR return fromReaderTaskEither(RTE.leftReader(me)) } -/** - * @category constructors - * @since 2.0.0 - */ -export function fromIOEither(ma: IOEither): StateReaderTaskEither { - return fromReaderTaskEither(RTE.fromIOEither(ma)) -} - -/** - * @category constructors - * @since 2.0.0 - */ -export function fromReaderEither(ma: ReaderEither): StateReaderTaskEither { - return fromReaderTaskEither(RTE.fromReaderEither(ma)) -} - /** * @category constructors * @since 2.0.0 @@ -162,80 +163,106 @@ export const leftState: (me: State) => StateRe s ) => RTE.left(me(s)[0]) +// ------------------------------------------------------------------------------------- +// natural transformations +// ------------------------------------------------------------------------------------- + /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ -export const fromReaderTaskEither: (ma: ReaderTaskEither) => StateReaderTaskEither = +export const fromEither: FromEither4['fromEither'] = /*#__PURE__*/ - ST.fromF(RTE.Functor) + E.match((e) => left(e), right) /** - * Get the current state - * - * @category constructors - * @since 2.0.0 + * @category natural transformations + * @since 2.11.0 */ -export const get = (): StateReaderTaskEither => (s) => RTE.of([s, s]) +export const fromReader: FromReader4['fromReader'] = rightReader /** - * Set the state - * - * @category constructors - * @since 2.0.0 + * @category natural transformations + * @since 2.7.0 */ -export const put = (s: S): StateReaderTaskEither => () => RTE.of([undefined, s]) +export const fromIO: FromIO4['fromIO'] = rightIO /** - * Modify the state by applying a function to the current state - * - * @category constructors - * @since 2.0.0 + * @category natural transformations + * @since 2.7.0 */ -export const modify = (f: (s: S) => S): StateReaderTaskEither => (s) => - RTE.of([undefined, f(s)]) +export const fromTask: FromTask4['fromTask'] = rightTask /** - * Get a value which depends on the current state - * - * @category constructors - * @since 2.0.0 + * @category natural transformations + * @since 2.10.0 */ -export const gets = (f: (s: S) => A): StateReaderTaskEither => (s) => - RTE.of([f(s), s]) +export const fromState: FromState4['fromState'] = + /*#__PURE__*/ + ST.fromState(RTE.Pointed) /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ -export const fromEither: (e: E.Either) => StateReaderTaskEither = - /*#__PURE__*/ - E.match((e) => left(e), right) +export const fromTaskEither: NaturalTransformation24 = (ma) => fromReaderTaskEither(RTE.fromTaskEither(ma)) /** - * @category constructors - * @since 2.7.0 + * @category natural transformations + * @since 2.0.0 */ -export const fromIO: FromIO4['fromIO'] = rightIO +export const fromIOEither: NaturalTransformation24 = (ma) => fromReaderTaskEither(RTE.fromIOEither(ma)) /** - * @category constructors - * @since 2.7.0 + * @category natural transformations + * @since 2.0.0 */ -export const fromTask: FromTask4['fromTask'] = rightTask +export const fromReaderEither: NaturalTransformation34 = (ma) => + fromReaderTaskEither(RTE.fromReaderEither(ma)) /** * @category constructors - * @since 2.10.0 + * @since 2.0.0 */ -export const fromState: (sa: State) => StateReaderTaskEither = +export const fromReaderTaskEither: NaturalTransformation34 = /*#__PURE__*/ - ST.fromState(RTE.Pointed) + ST.fromF(RTE.Functor) // ------------------------------------------------------------------------------------- // combinators // ------------------------------------------------------------------------------------- +/** + * Changes the value of the local context during the execution of the action `ma` (similar to `Contravariant`'s + * `contramap`). + * + * @category combinators + * @since 2.11.0 + */ +export const local = (f: (r2: R2) => R1) => ( + ma: StateReaderTaskEither +): StateReaderTaskEither => flow(ma, R.local(f)) + +/** + * Less strict version of [`asksStateReaderTaskEither`](#asksstatereadertaskeither). + * + * @category combinators + * @since 2.11.0 + */ +export const asksStateReaderTaskEitherW = ( + f: (r1: R1) => StateReaderTaskEither +): StateReaderTaskEither => (s) => (r) => f(r)(s)(r) + +/** + * Effectfully accesses the environment. + * + * @category combinators + * @since 2.11.0 + */ +export const asksStateReaderTaskEither: ( + f: (r: R) => StateReaderTaskEither +) => StateReaderTaskEither = asksStateReaderTaskEitherW + /** * @category combinators * @since 2.4.0 @@ -292,11 +319,9 @@ export const chainTaskEitherK: ( * @category combinators * @since 2.4.0 */ -export function fromReaderTaskEitherK, B>( +export const fromReaderTaskEitherK = , B>( f: (...a: A) => ReaderTaskEither -): (...a: A) => StateReaderTaskEither { - return (...a) => fromReaderTaskEither(f(...a)) -} +): ((...a: A) => StateReaderTaskEither) => (...a) => fromReaderTaskEither(f(...a)) /** * Less strict version of [`chainReaderTaskEitherK`](#chainreadertaskeitherk). @@ -441,6 +466,18 @@ export const chainW: ( f: (a: A) => StateReaderTaskEither ) => (ma: StateReaderTaskEither) => StateReaderTaskEither = chain as any +/** + * Less strict version of [`flatten`](#flatten). + * + * @category combinators + * @since 2.11.0 + */ +export const flattenW: ( + mma: StateReaderTaskEither> +) => StateReaderTaskEither = + /*#__PURE__*/ + chainW(identity) + /** * Derivable from `Chain`. * @@ -449,9 +486,7 @@ export const chainW: ( */ export const flatten: ( mma: StateReaderTaskEither> -) => StateReaderTaskEither = - /*#__PURE__*/ - chain(identity) +) => StateReaderTaskEither = flattenW /** * Less strict version of [`alt`](#alt). @@ -590,6 +625,75 @@ export const Chain: Chain4 = { chain: _chain } +/** + * @category instances + * @since 2.11.0 + */ +export const FromState: FromState4 = { + URI, + fromState +} + +/** + * Get the current state + * + * @category constructors + * @since 2.0.0 + */ +export const get: () => StateReaderTaskEither = + /*#__PURE__*/ + get_(FromState) + +/** + * Set the state + * + * @category constructors + * @since 2.0.0 + */ +export const put: (s: S) => StateReaderTaskEither = + /*#__PURE__*/ + put_(FromState) + +/** + * Modify the state by applying a function to the current state + * + * @category constructors + * @since 2.0.0 + */ +export const modify: (f: Endomorphism) => StateReaderTaskEither = + /*#__PURE__*/ + modify_(FromState) + +/** + * Get a value which depends on the current state + * + * @category constructors + * @since 2.0.0 + */ +export const gets: (f: (s: S) => A) => StateReaderTaskEither = + /*#__PURE__*/ + gets_(FromState) + +/** + * @category combinators + * @since 2.11.0 + */ +export const fromStateK: , S, B>( + f: (...a: A) => State +) => (...a: A) => StateReaderTaskEither = + /*#__PURE__*/ + fromStateK_(FromState) + +/** + * @category combinators + * @since 2.11.0 + */ +export const chainStateK: ( + f: (a: A) => State +) => (ma: StateReaderTaskEither) => StateReaderTaskEither = + /*#__PURE__*/ + chainStateK_(FromState, Chain) + /** * @category instances * @since 2.10.0 @@ -691,6 +795,89 @@ export const Alt: Alt4 = { alt: _alt } +/** + * @category instances + * @since 2.11.0 + */ +export const FromReader: FromReader4 = { + URI, + fromReader +} + +/** + * Reads the current context. + * + * @category constructors + * @since 2.11.0 + */ +export const ask: () => StateReaderTaskEither = + /*#__PURE__*/ + ask_(FromReader) + +/** + * Projects a value from the global context in a `ReaderEither`. + * + * @category constructors + * @since 2.11.0 + */ +export const asks: (f: (r: R) => A) => StateReaderTaskEither = + /*#__PURE__*/ + asks_(FromReader) + +/** + * @category combinators + * @since 2.11.0 + */ +export const fromReaderK: , R, B>( + f: (...a: A) => Reader +) => (...a: A) => StateReaderTaskEither = + /*#__PURE__*/ + fromReaderK_(FromReader) + +/** + * @category combinators + * @since 2.11.0 + */ +export const chainReaderK: ( + f: (a: A) => Reader +) => (ma: StateReaderTaskEither) => StateReaderTaskEither = + /*#__PURE__*/ + chainReaderK_(FromReader, Chain) + +/** + * Less strict version of [`chainReaderK`](#chainReaderK). + * + * @category combinators + * @since 2.11.0 + */ +export const chainReaderKW: ( + f: (a: A) => Reader +) => ( + ma: StateReaderTaskEither +) => StateReaderTaskEither = chainReaderK as any + +/** + * @category combinators + * @since 2.11.0 + */ +export const chainFirstReaderK: ( + f: (a: A) => Reader +) => (ma: StateReaderTaskEither) => StateReaderTaskEither = + /*#__PURE__*/ + chainFirstReaderK_(FromReader, Chain) + +/** + * Less strict version of [`chainFirstReaderK`](#chainFirstReaderK). + * + * @category combinators + * @since 2.11.0 + */ +export const chainFirstReaderKW: ( + f: (a: A) => Reader +) => ( + ma: StateReaderTaskEither +) => StateReaderTaskEither = chainFirstReaderK as any + /** * @category instances * @since 2.10.0 @@ -701,10 +888,10 @@ export const FromEither: FromEither4 = { } /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ -export const fromOption: (onNone: Lazy) => (ma: Option) => StateReaderTaskEither = +export const fromOption: (onNone: Lazy) => NaturalTransformation14C = /*#__PURE__*/ fromOption_(FromEither) @@ -752,6 +939,7 @@ export const fromPredicate: { (refinement: Refinement, onFalse: (a: A) => E): ( a: A ) => StateReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => StateReaderTaskEither (predicate: Predicate, onFalse: (a: A) => E): (a: A) => StateReaderTaskEither } = /*#__PURE__*/ @@ -765,6 +953,9 @@ export const filterOrElse: { (refinement: Refinement, onFalse: (a: A) => E): ( ma: StateReaderTaskEither ) => StateReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E): ( + mb: StateReaderTaskEither + ) => StateReaderTaskEither (predicate: Predicate, onFalse: (a: A) => E): ( ma: StateReaderTaskEither ) => StateReaderTaskEither @@ -782,6 +973,9 @@ export const filterOrElseW: { (refinement: Refinement, onFalse: (a: A) => E2): ( ma: StateReaderTaskEither ) => StateReaderTaskEither + (predicate: Predicate, onFalse: (a: A) => E2): ( + mb: StateReaderTaskEither + ) => StateReaderTaskEither (predicate: Predicate, onFalse: (a: A) => E2): ( ma: StateReaderTaskEither ) => StateReaderTaskEither @@ -950,23 +1144,23 @@ export const apSW: ( // ------------------------------------------------------------------------------------- /** - * Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(Applicative)`. * - * @since 2.9.0 + * @since 2.11.0 */ -export const traverseArrayWithIndex = ( +export const traverseReadonlyNonEmptyArrayWithIndex = ( f: (index: number, a: A) => StateReaderTaskEither -) => (as: ReadonlyArray): StateReaderTaskEither> => (s) => (r) => () => - as.reduce, S]>>>( +) => (as: ReadonlyNonEmptyArray): StateReaderTaskEither> => (s) => (r) => () => + _.tail(as).reduce, S]>>>( (acc, a, i) => acc.then((ebs) => - E.isLeft(ebs) + _.isLeft(ebs) ? acc : f( - i, + i + 1, a )(ebs.right[1])(r)().then((eb) => { - if (E.isLeft(eb)) { + if (_.isLeft(eb)) { return eb } const [b, s] = eb.right @@ -975,22 +1169,37 @@ export const traverseArrayWithIndex = ( return ebs }) ), - Promise.resolve(E.right([[], s])) + f(0, _.head(as))(s)(r)().then(E.map(([b, s]) => [[b], s])) ) /** - * Equivalent to `ReadonlyArray#traverse(Applicative)`. + * Equivalent to `ReadonlyArray#traverseWithIndex(Applicative)`. * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndex = ( + f: (index: number, a: A) => StateReaderTaskEither +): ((as: ReadonlyArray) => StateReaderTaskEither>) => { + const g = traverseReadonlyNonEmptyArrayWithIndex(f) + return (as) => (_.isNonEmpty(as) ? g(as) : of(_.emptyReadonlyArray)) +} + +/** + * @since 2.9.0 + */ +export const traverseArrayWithIndex: ( + f: (index: number, a: A) => StateReaderTaskEither +) => (as: ReadonlyArray) => StateReaderTaskEither> = traverseReadonlyArrayWithIndex + +/** * @since 2.9.0 */ export const traverseArray = ( f: (a: A) => StateReaderTaskEither ): ((as: ReadonlyArray) => StateReaderTaskEither>) => - traverseArrayWithIndex((_, a) => f(a)) + traverseReadonlyArrayWithIndex((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(Applicative)`. - * * @since 2.9.0 */ export const sequenceArray: ( diff --git a/src/Store.ts b/src/Store.ts index af1e54f51..ce348e314 100644 --- a/src/Store.ts +++ b/src/Store.ts @@ -2,10 +2,11 @@ * @since 2.0.0 */ import { Comonad2 } from './Comonad' -import { Endomorphism, identity, pipe } from './function' +import { Endomorphism } from './Endomorphism' +import { Extend2 } from './Extend' +import { identity, pipe } from './function' import { flap as flap_, Functor as FunctorHKT, Functor1, Functor2, Functor2C, Functor3, Functor3C } from './Functor' import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT' -import { Extend2 } from './Extend' // ------------------------------------------------------------------------------------- // model diff --git a/src/Task.ts b/src/Task.ts index 2904ec145..3efe7244a 100644 --- a/src/Task.ts +++ b/src/Task.ts @@ -23,11 +23,14 @@ import { chainFirstIOK as chainFirstIOK_, chainIOK as chainIOK_, FromIO1, fromIO import { FromTask1 } from './FromTask' import { identity, pipe } from './function' import { bindTo as bindTo_, flap as flap_, Functor1 } from './Functor' +import * as _ from './internal' import { Monad1 } from './Monad' import { MonadIO1 } from './MonadIO' import { MonadTask1 } from './MonadTask' import { Monoid } from './Monoid' +import { NonEmptyArray } from './NonEmptyArray' import { Pointed1 } from './Pointed' +import { ReadonlyNonEmptyArray } from './ReadonlyNonEmptyArray' import { Semigroup } from './Semigroup' // ------------------------------------------------------------------------------------- @@ -43,11 +46,11 @@ export interface Task { } // ------------------------------------------------------------------------------------- -// constructors +// natural transformations // ------------------------------------------------------------------------------------- /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ export const fromIO: FromIO1['fromIO'] = (ma) => () => Promise.resolve(ma()) @@ -96,14 +99,14 @@ export function delay(millis: number): (ma: Task) => Task { // non-pipeables // ------------------------------------------------------------------------------------- -const _map: Monad1['map'] = (fa, f) => pipe(fa, map(f)) -const _apPar: Monad1['ap'] = (fab, fa) => pipe(fab, ap(fa)) -const _apSeq: Monad1['ap'] = (fab, fa) => +const _map: Functor1['map'] = (fa, f) => pipe(fa, map(f)) +const _apPar: Apply1['ap'] = (fab, fa) => pipe(fab, ap(fa)) +const _apSeq: Apply1['ap'] = (fab, fa) => pipe( fab, chain((f) => pipe(fa, map(f))) ) -const _chain: Monad1['chain'] = (ma, f) => pipe(ma, chain(f)) +const _chain: Chain1['chain'] = (ma, f) => pipe(ma, chain(f)) // ------------------------------------------------------------------------------------- // type class members @@ -152,13 +155,6 @@ export const flatten: (mma: Task>) => Task = /*#__PURE__*/ chain(identity) -/** - * @category FromTask - * @since 2.7.0 - * @deprecated - */ -export const fromTask: FromTask1['fromTask'] = identity - // ------------------------------------------------------------------------------------- // instances // ------------------------------------------------------------------------------------- @@ -338,6 +334,13 @@ export const MonadIO: MonadIO1 = { fromIO } +/** + * @category FromTask + * @since 2.7.0 + * @deprecated + */ +export const fromTask: FromTask1['fromTask'] = identity + /** * @category instances * @since 2.10.0 @@ -428,7 +431,7 @@ export const never: Task = () => new Promise((_) => undefined) */ export const Do: Task<{}> = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 @@ -456,65 +459,104 @@ export const apS = apS_(ApplyPar) // ------------------------------------------------------------------------------------- -// array utils +// sequence T // ------------------------------------------------------------------------------------- /** - * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. - * - * @since 2.9.0 + * @since 2.11.0 */ -export const traverseArrayWithIndex = (f: (index: number, a: A) => Task) => ( - as: ReadonlyArray -): Task> => () => Promise.all(as.map((x, i) => f(i, x)())) +export const ApT: Task = of(_.emptyReadonlyArray) + +// ------------------------------------------------------------------------------------- +// array utils +// ------------------------------------------------------------------------------------- /** - * Equivalent to `ReadonlyArray#traverse(ApplicativePar)`. + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativePar)`. * - * @since 2.9.0 + * @since 2.11.0 */ -export const traverseArray = (f: (a: A) => Task): ((as: ReadonlyArray) => Task>) => - traverseArrayWithIndex((_, a) => f(a)) +export const traverseReadonlyNonEmptyArrayWithIndex = (f: (index: number, a: A) => Task) => ( + as: ReadonlyNonEmptyArray +): Task> => () => Promise.all(as.map((a, i) => f(i, a)())) as any /** - * Equivalent to `ReadonlyArray#sequence(ApplicativePar)`. + * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. * - * @since 2.9.0 + * @since 2.11.0 */ -export const sequenceArray: (arr: ReadonlyArray>) => Task> = - /*#__PURE__*/ - traverseArray(identity) +export const traverseReadonlyArrayWithIndex = ( + f: (index: number, a: A) => Task +): ((as: ReadonlyArray) => Task>) => { + const g = traverseReadonlyNonEmptyArrayWithIndex(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} /** - * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativeSeq)`. * - * @since 2.9.0 + * @since 2.11.0 */ -export const traverseSeqArrayWithIndex = (f: (index: number, a: A) => Task) => ( - as: ReadonlyArray -): Task> => () => - as.reduce>>( +export const traverseReadonlyNonEmptyArrayWithIndexSeq = (f: (index: number, a: A) => Task) => ( + as: ReadonlyNonEmptyArray +): Task> => () => + _.tail(as).reduce>>( (acc, a, i) => acc.then((bs) => - f(i, a)().then((b) => { + f(i + 1, a)().then((b) => { bs.push(b) return bs }) ), - Promise.resolve([]) + f(0, _.head(as))().then(_.singleton) ) /** - * Equivalent to `ReadonlyArray#traverse(ApplicativeSeq)`. + * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndexSeq = ( + f: (index: number, a: A) => Task +): ((as: ReadonlyArray) => Task>) => { + const g = traverseReadonlyNonEmptyArrayWithIndexSeq(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + +/** + * @since 2.9.0 + */ +export const traverseArrayWithIndex: ( + f: (index: number, a: A) => Task +) => (as: ReadonlyArray) => Task> = traverseReadonlyArrayWithIndex + +/** + * @since 2.9.0 + */ +export const traverseArray = (f: (a: A) => Task): ((as: ReadonlyArray) => Task>) => + traverseReadonlyArrayWithIndex((_, a) => f(a)) + +/** + * @since 2.9.0 + */ +export const sequenceArray: (arr: ReadonlyArray>) => Task> = + /*#__PURE__*/ + traverseArray(identity) + +/** + * @since 2.9.0 + */ +export const traverseSeqArrayWithIndex: ( + f: (index: number, a: A) => Task +) => (as: ReadonlyArray) => Task> = traverseReadonlyArrayWithIndexSeq + +/** * @since 2.9.0 */ export const traverseSeqArray = (f: (a: A) => Task): ((as: ReadonlyArray) => Task>) => - traverseSeqArrayWithIndex((_, a) => f(a)) + traverseReadonlyArrayWithIndexSeq((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(ApplicativeSeq)`. - * * @since 2.9.0 */ export const sequenceSeqArray: (arr: ReadonlyArray>) => Task> = @@ -551,7 +593,6 @@ export const task: Monad1 & MonadTask1 = { * @since 2.0.0 * @deprecated */ - export const taskSeq: typeof task = { URI, map: _map, diff --git a/src/TaskEither.ts b/src/TaskEither.ts index 465fdd3d6..4a1243d7d 100644 --- a/src/TaskEither.ts +++ b/src/TaskEither.ts @@ -48,19 +48,25 @@ import { FromTask2, fromTaskK as fromTaskK_ } from './FromTask' -import { flow, identity, Lazy, pipe, Predicate, Refinement } from './function' +import { flow, identity, Lazy, pipe, SK } from './function' import { bindTo as bindTo_, flap as flap_, Functor2 } from './Functor' +import * as _ from './internal' import { IO } from './IO' -import { IOEither } from './IOEither' +import { IOEither, URI as IEURI } from './IOEither' import { Monad2, Monad2C } from './Monad' import { MonadIO2 } from './MonadIO' import { MonadTask2, MonadTask2C } from './MonadTask' import { MonadThrow2, MonadThrow2C } from './MonadThrow' import { Monoid } from './Monoid' -import { Option } from './Option' +import { NaturalTransformation12C, NaturalTransformation22 } from './NaturalTransformation' +import { NonEmptyArray } from './NonEmptyArray' import { Pointed2 } from './Pointed' +import { Predicate } from './Predicate' +import { ReadonlyNonEmptyArray } from './ReadonlyNonEmptyArray' +import { Refinement } from './Refinement' import { Semigroup } from './Semigroup' import * as T from './Task' +import { TaskOption, URI as TOURI } from './TaskOption' // ------------------------------------------------------------------------------------- // model @@ -127,29 +133,40 @@ export const leftIO: (me: IO) => TaskEither = /*#__PURE__*/ flow(T.fromIO, leftTask) +// ------------------------------------------------------------------------------------- +// natural transformations +// ------------------------------------------------------------------------------------- + /** - * @category constructors - * @since 2.0.0 + * @category natural transformations + * @since 2.7.0 + */ +export const fromIO: FromIO2['fromIO'] = rightIO + +/** + * @category natural transformations + * @since 2.7.0 */ -export const fromIOEither: (fa: IOEither) => TaskEither = T.fromIO +export const fromTask: FromTask2['fromTask'] = rightTask /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ export const fromEither: FromEither2['fromEither'] = T.of /** - * @category constructors - * @since 2.7.0 + * @category natural transformations + * @since 2.0.0 */ -export const fromIO: FromIO2['fromIO'] = rightIO +export const fromIOEither: NaturalTransformation22 = T.fromIO /** - * @category constructors - * @since 2.7.0 + * @category natural transformations + * @since 2.11.0 */ -export const fromTask: FromTask2['fromTask'] = rightTask +export const fromTaskOption: (onNone: Lazy) => NaturalTransformation12C = (onNone) => + T.map(E.fromOption(onNone)) // ------------------------------------------------------------------------------------- // destructors @@ -256,7 +273,7 @@ export const getOrElseW: ( * @since 2.0.0 */ export const tryCatch = (f: Lazy>, onRejected: (reason: unknown) => E): TaskEither => () => - f().then(E.right, (reason) => E.left(onRejected(reason))) + f().then(_.right, (reason) => _.left(onRejected(reason))) /** * Converts a function returning a `Promise` to one returning a `TaskEither`. @@ -316,6 +333,30 @@ export const orElseW: ( onLeft: (e: E1) => TaskEither ) => (ma: TaskEither) => TaskEither = orElse as any +/** + * @category combinators + * @since 2.11.0 + */ +export const orElseFirst: (onLeft: (e: E) => TaskEither) => (ma: TaskEither) => TaskEither = + /*#__PURE__*/ + ET.orElseFirst(T.Monad) + +/** + * @category combinators + * @since 2.11.0 + */ +export const orElseFirstW: ( + onLeft: (e: E1) => TaskEither +) => (ma: TaskEither) => TaskEither = orElseFirst as any + +/** + * @category combinators + * @since 2.11.0 + */ +export const orLeft: (onLeft: (e: E1) => Task) => (fa: TaskEither) => TaskEither = + /*#__PURE__*/ + ET.orLeft(T.Monad) + /** * @category combinators * @since 2.0.0 @@ -324,6 +365,26 @@ export const swap: (ma: TaskEither) => TaskEither = /*#__PURE__*/ ET.swap(T.Functor) +/** + * @category combinators + * @since 2.11.0 + */ +export const fromTaskOptionK = ( + onNone: Lazy +): (, B>(f: (...a: A) => TaskOption) => (...a: A) => TaskEither) => { + const from = fromTaskOption(onNone) + return (f) => flow(f, from) +} + +/** + * @category combinators + * @since 2.11.0 + */ +export const chainTaskOptionK = ( + onNone: Lazy +): ((f: (a: A) => TaskOption) => (ma: TaskEither) => TaskEither) => + flow(fromTaskOptionK(onNone), chain) + /** * @category combinators * @since 2.4.0 @@ -354,19 +415,19 @@ export const chainIOEitherK: ( // non-pipeables // ------------------------------------------------------------------------------------- -const _map: Monad2['map'] = (fa, f) => pipe(fa, map(f)) -/* istanbul ignore next */ -const _bimap: Bifunctor2['bimap'] = (fa, f, g) => pipe(fa, bimap(f, g)) -/* istanbul ignore next */ -const _mapLeft: Bifunctor2['mapLeft'] = (fa, f) => pipe(fa, mapLeft(f)) -const _apPar: Monad2['ap'] = (fab, fa) => pipe(fab, ap(fa)) -const _apSeq: Applicative2['ap'] = (fab, fa) => +const _map: Functor2['map'] = (fa, f) => pipe(fa, map(f)) +const _apPar: Apply2['ap'] = (fab, fa) => pipe(fab, ap(fa)) +const _apSeq: Apply2['ap'] = (fab, fa) => pipe( fab, chain((f) => pipe(fa, map(f))) ) /* istanbul ignore next */ -const _chain: Monad2['chain'] = (ma, f) => pipe(ma, chain(f)) +const _chain: Chain2['chain'] = (ma, f) => pipe(ma, chain(f)) +/* istanbul ignore next */ +const _bimap: Bifunctor2['bimap'] = (fa, f, g) => pipe(fa, bimap(f, g)) +/* istanbul ignore next */ +const _mapLeft: Bifunctor2['mapLeft'] = (fa, f) => pipe(fa, mapLeft(f)) /* istanbul ignore next */ const _alt: Alt2['alt'] = (fa, that) => pipe(fa, alt(that)) @@ -445,15 +506,23 @@ export const chainW: ( f: (a: A) => TaskEither ) => (ma: TaskEither) => TaskEither = chain as any +/** + * Less strict version of [`flatten`](#flatten). + * + * @category combinators + * @since 2.11.0 + */ +export const flattenW: (mma: TaskEither>) => TaskEither = + /*#__PURE__*/ + chainW(identity) + /** * Derivable from `Chain`. * * @category combinators * @since 2.0.0 */ -export const flatten: (mma: TaskEither>) => TaskEither = - /*#__PURE__*/ - chain(identity) +export const flatten: (mma: TaskEither>) => TaskEither = flattenW /** * Identifies an associative operation on a type constructor. It is similar to `Semigroup`, except that it applies to @@ -825,10 +894,10 @@ export const FromEither: FromEither2 = { } /** - * @category constructors + * @category natural transformations * @since 2.0.0 */ -export const fromOption: (onNone: Lazy) => (ma: Option) => TaskEither = +export const fromOption = /*#__PURE__*/ fromOption_(FromEither) @@ -872,6 +941,7 @@ export const chainEitherKW: ( */ export const fromPredicate: { (refinement: Refinement, onFalse: (a: A) => E): (a: A) => TaskEither + (predicate: Predicate, onFalse: (a: A) => E): (b: B) => TaskEither (predicate: Predicate, onFalse: (a: A) => E): (a: A) => TaskEither } = /*#__PURE__*/ @@ -883,6 +953,7 @@ export const fromPredicate: { */ export const filterOrElse: { (refinement: Refinement, onFalse: (a: A) => E): (ma: TaskEither) => TaskEither + (predicate: Predicate, onFalse: (a: A) => E): (mb: TaskEither) => TaskEither (predicate: Predicate, onFalse: (a: A) => E): (ma: TaskEither) => TaskEither } = /*#__PURE__*/ @@ -898,6 +969,9 @@ export const filterOrElseW: { (refinement: Refinement, onFalse: (a: A) => E2): ( ma: TaskEither ) => TaskEither + (predicate: Predicate, onFalse: (a: A) => E2): ( + mb: TaskEither + ) => TaskEither (predicate: Predicate, onFalse: (a: A) => E2): (ma: TaskEither) => TaskEither } = filterOrElse @@ -1030,7 +1104,7 @@ export function taskify(f: Function): () => TaskEither { const args = Array.prototype.slice.call(arguments) return () => new Promise((resolve) => { - const cbResolver = (e: L, r: R) => (e != null ? resolve(E.left(e)) : resolve(E.right(r))) + const cbResolver = (e: L, r: R) => (e != null ? resolve(_.left(e)) : resolve(_.right(r))) f.apply(null, args.concat(cbResolver)) }) } @@ -1073,7 +1147,7 @@ export const bracket = ( */ export const Do: TaskEither = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 @@ -1121,73 +1195,112 @@ export const apSW: ( ) => TaskEither = apS as any // ------------------------------------------------------------------------------------- -// array utils +// sequence T // ------------------------------------------------------------------------------------- /** - * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. - * - * @since 2.9.0 + * @since 2.11.0 */ -export const traverseArrayWithIndex = ( - f: (index: number, a: A) => TaskEither -): ((as: ReadonlyArray) => TaskEither>) => - flow(T.traverseArrayWithIndex(f), T.map(E.sequenceArray)) +export const ApT: TaskEither = of(_.emptyReadonlyArray) + +// ------------------------------------------------------------------------------------- +// array utils +// ------------------------------------------------------------------------------------- /** - * Equivalent to `ReadonlyArray#traverse(ApplicativePar)`. + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativePar)`. * - * @since 2.9.0 + * @since 2.11.0 */ -export const traverseArray = ( - f: (a: A) => TaskEither -): ((as: ReadonlyArray) => TaskEither>) => traverseArrayWithIndex((_, a) => f(a)) +export const traverseReadonlyNonEmptyArrayWithIndex = ( + f: (index: number, a: A) => TaskEither +): ((as: ReadonlyNonEmptyArray) => TaskEither>) => + flow(T.traverseReadonlyNonEmptyArrayWithIndex(f), T.map(E.traverseReadonlyNonEmptyArrayWithIndex(SK))) /** - * Equivalent to `ReadonlyArray#sequence(ApplicativePar)`. + * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. * - * @since 2.9.0 + * @since 2.11.0 */ -export const sequenceArray: (arr: ReadonlyArray>) => TaskEither> = - /*#__PURE__*/ - traverseArray(identity) +export const traverseReadonlyArrayWithIndex = ( + f: (index: number, a: A) => TaskEither +): ((as: ReadonlyArray) => TaskEither>) => { + const g = traverseReadonlyNonEmptyArrayWithIndex(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} /** * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. * - * @since 2.9.0 + * @since 2.11.0 */ -export const traverseSeqArrayWithIndex = (f: (index: number, a: A) => TaskEither) => ( - as: ReadonlyArray -): TaskEither> => () => - as.reduce>>>( +export const traverseReadonlyNonEmptyArrayWithIndexSeq = (f: (index: number, a: A) => TaskEither) => ( + as: ReadonlyNonEmptyArray +): TaskEither> => () => + _.tail(as).reduce>>>( (acc, a, i) => acc.then((ebs) => - E.isLeft(ebs) + _.isLeft(ebs) ? acc - : f(i, a)().then((eb) => { - if (E.isLeft(eb)) { + : f(i + 1, a)().then((eb) => { + if (_.isLeft(eb)) { return eb } ebs.right.push(eb.right) return ebs }) ), - Promise.resolve(E.right([])) + f(0, _.head(as))().then(E.map(_.singleton)) ) /** - * Equivalent to `ReadonlyArray#traverse(ApplicativeSeq)`. + * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndexSeq = ( + f: (index: number, a: A) => TaskEither +): ((as: ReadonlyArray) => TaskEither>) => { + const g = traverseReadonlyNonEmptyArrayWithIndexSeq(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + +/** + * @since 2.9.0 + */ +export const traverseArrayWithIndex: ( + f: (index: number, a: A) => TaskEither +) => (as: ReadonlyArray) => TaskEither> = traverseReadonlyArrayWithIndex + +/** + * @since 2.9.0 + */ +export const traverseArray = ( + f: (a: A) => TaskEither +): ((as: ReadonlyArray) => TaskEither>) => traverseReadonlyArrayWithIndex((_, a) => f(a)) + +/** + * @since 2.9.0 + */ +export const sequenceArray: (arr: ReadonlyArray>) => TaskEither> = + /*#__PURE__*/ + traverseArray(identity) + +/** + * @since 2.9.0 + */ +export const traverseSeqArrayWithIndex: ( + f: (index: number, a: A) => TaskEither +) => (as: ReadonlyArray) => TaskEither> = traverseReadonlyArrayWithIndexSeq + +/** * @since 2.9.0 */ export const traverseSeqArray = ( f: (a: A) => TaskEither -): ((as: ReadonlyArray) => TaskEither>) => traverseSeqArrayWithIndex((_, a) => f(a)) +): ((as: ReadonlyArray) => TaskEither>) => traverseReadonlyArrayWithIndexSeq((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(ApplicativeSeq)`. - * * @since 2.9.0 */ export const sequenceSeqArray: (arr: ReadonlyArray>) => TaskEither> = diff --git a/src/TaskOption.ts b/src/TaskOption.ts index 59ee088d9..c528b7017 100644 --- a/src/TaskOption.ts +++ b/src/TaskOption.ts @@ -15,6 +15,7 @@ import { partition as partition_, partitionMap as partitionMap_ } from './Filterable' +import { FromEither1 } from './FromEither' import { chainFirstIOK as chainFirstIOK_, chainIOK as chainIOK_, FromIO1, fromIOK as fromIOK_ } from './FromIO' import { chainFirstTaskK as chainFirstTaskK_, @@ -22,16 +23,24 @@ import { FromTask1, fromTaskK as fromTaskK_ } from './FromTask' -import { flow, identity, Lazy, pipe, Predicate, Refinement } from './function' +import { flow, identity, Lazy, pipe, SK } from './function' import { bindTo as bindTo_, flap as flap_, Functor1 } from './Functor' +import * as _ from './internal' import { Monad1 } from './Monad' import { MonadIO1 } from './MonadIO' import { MonadTask1 } from './MonadTask' +import { NaturalTransformation11, NaturalTransformation21 } from './NaturalTransformation' +import { NonEmptyArray } from './NonEmptyArray' import * as O from './Option' import * as OT from './OptionT' import { Pointed1 } from './Pointed' +import { Predicate } from './Predicate' +import { ReadonlyNonEmptyArray } from './ReadonlyNonEmptyArray' +import { Refinement } from './Refinement' import { Separated } from './Separated' import * as T from './Task' +import { URI as TEURI } from './TaskEither' +import { Zero1, guard as guard_ } from './Zero' import Task = T.Task import Option = O.Option @@ -58,45 +67,58 @@ export const some: (a: A) => TaskOption = /*#__PURE__*/ OT.some(T.Pointed) -/** - * @category constructors - * @since 2.10.0 - */ -export const fromOption: (ma: Option) => TaskOption = T.of - /** * @category constructors * @since 2.10.0 */ export const fromPredicate: { (refinement: Refinement): (a: A) => TaskOption + (predicate: Predicate): (b: B) => TaskOption (predicate: Predicate): (a: A) => TaskOption } = /*#__PURE__*/ OT.fromPredicate(T.Pointed) +// ------------------------------------------------------------------------------------- +// natural transformations +// ------------------------------------------------------------------------------------- + /** - * @category constructors + * @category natural transformations + * @since 2.10.0 + */ +export const fromOption: NaturalTransformation11 = T.of + +/** + * @category natural transformations * @since 2.10.0 */ -export const fromEither: (e: Either) => TaskOption = +export const fromEither: FromEither1['fromEither'] = /*#__PURE__*/ OT.fromEither(T.Pointed) /** - * @category constructors + * @category natural transformations * @since 2.10.0 */ export const fromIO: FromIO1['fromIO'] = (ma) => fromTask(T.fromIO(ma)) /** - * @category constructors + * @category natural transformations * @since 2.10.0 */ export const fromTask: FromTask1['fromTask'] = /*#__PURE__*/ OT.fromF(T.Functor) +/** + * @category natural transformations + * @since 2.11.0 + */ +export const fromTaskEither: NaturalTransformation21 = + /*#__PURE__*/ + T.map(O.fromEither) + // ------------------------------------------------------------------------------------- // destructors // ------------------------------------------------------------------------------------- @@ -315,10 +337,10 @@ export const alt: (second: Lazy>) => (first: TaskOption) => export const altW: (second: Lazy>) => (first: TaskOption) => TaskOption = alt as any /** - * @category Alternative + * @category Zero * @since 2.10.0 */ -export const zero: Alternative1['zero'] = +export const zero: Zero1['zero'] = /*#__PURE__*/ OT.zero(T.Pointed) @@ -350,7 +372,11 @@ export const separate: Compactable1['separate'] = * @category Filterable * @since 2.10.0 */ -export const filter: (predicate: Predicate) => (fga: TaskOption) => TaskOption = +export const filter: { + (refinement: Refinement): (fb: TaskOption) => TaskOption + (predicate: Predicate): (fb: TaskOption) => TaskOption + (predicate: Predicate): (fa: TaskOption) => TaskOption +} = /*#__PURE__*/ filter_(T.Functor, O.Filterable) @@ -366,9 +392,11 @@ export const filterMap: (f: (a: A) => Option) => (fga: TaskOption) = * @category Filterable * @since 2.10.0 */ -export const partition: ( - predicate: Predicate -) => (fga: TaskOption) => Separated, TaskOption> = +export const partition: { + (refinement: Refinement): (fb: TaskOption) => Separated, TaskOption> + (predicate: Predicate): (fb: TaskOption) => Separated, TaskOption> + (predicate: Predicate): (fa: TaskOption) => Separated, TaskOption> +} = /*#__PURE__*/ partition_(T.Functor, O.Filterable) @@ -555,6 +583,23 @@ export const Alt: Alt1 = { alt: _alt } +/** + * @category instances + * @since 2.11.0 + */ +export const Zero: Zero1 = { + URI, + zero +} + +/** + * @category constructors + * @since 2.11.0 + */ +export const guard = + /*#__PURE__*/ + guard_(Zero, Pointed) + /** * @category instances * @since 2.10.0 @@ -665,6 +710,15 @@ export const chainFirstIOK = /*#__PURE__*/ chainFirstIOK_(FromIO, Chain) +/** + * @category instances + * @since 2.11.0 + */ +export const FromEither: FromEither1 = { + URI, + fromEither +} + /** * @category instances * @since 2.10.0 @@ -708,7 +762,7 @@ export const chainFirstTaskK = */ export const Do: TaskOption<{}> = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.10.0 @@ -736,74 +790,120 @@ export const apS = apS_(ApplyPar) // ------------------------------------------------------------------------------------- -// array utils +// sequence T // ------------------------------------------------------------------------------------- /** - * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. - * - * @since 2.10.0 + * @since 2.11.0 */ -export const traverseArrayWithIndex = ( - f: (index: number, a: A) => TaskOption -): ((as: ReadonlyArray) => TaskOption>) => flow(T.traverseArrayWithIndex(f), T.map(O.sequenceArray)) +export const ApT: TaskOption = of(_.emptyReadonlyArray) + +// ------------------------------------------------------------------------------------- +// array utils +// ------------------------------------------------------------------------------------- /** - * Equivalent to `ReadonlyArray#traverse(ApplicativePar)`. + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativePar)`. * - * @since 2.10.0 + * @since 2.11.0 */ -export const traverseArray: ( - f: (a: A) => TaskOption -) => (as: ReadonlyArray) => TaskOption> = (f) => traverseArrayWithIndex((_, a) => f(a)) +export const traverseReadonlyNonEmptyArrayWithIndex = ( + f: (index: number, a: A) => TaskOption +): ((as: ReadonlyNonEmptyArray) => TaskOption>) => + flow(T.traverseReadonlyNonEmptyArrayWithIndex(f), T.map(O.traverseReadonlyNonEmptyArrayWithIndex(SK))) /** - * Equivalent to `ReadonlyArray#sequence(ApplicativePar)`. + * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativePar)`. * - * @since 2.10.0 + * @since 2.11.0 */ -export const sequenceArray: (as: ReadonlyArray>) => TaskOption> = - /*#__PURE__*/ - traverseArray(identity) +export const traverseReadonlyArrayWithIndex = ( + f: (index: number, a: A) => TaskOption +): ((as: ReadonlyArray) => TaskOption>) => { + const g = traverseReadonlyNonEmptyArrayWithIndex(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} /** - * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(ApplicativeSeq)`. * - * @since 2.10.0 + * @since 2.11.0 */ -export const traverseSeqArrayWithIndex = (f: (index: number, a: A) => TaskOption) => ( - as: ReadonlyArray -): TaskOption> => () => - as.reduce>>>( +export const traverseReadonlyNonEmptyArrayWithIndexSeq = (f: (index: number, a: A) => TaskOption) => ( + as: ReadonlyNonEmptyArray +): TaskOption> => () => + _.tail(as).reduce>>>( (acc, a, i) => acc.then((obs) => - O.isNone(obs) + _.isNone(obs) ? acc - : f(i, a)().then((ob) => { - if (O.isNone(ob)) { + : f(i + 1, a)().then((ob) => { + if (_.isNone(ob)) { return ob } obs.value.push(ob.value) return obs }) ), - Promise.resolve(O.some([])) + f(0, _.head(as))().then(O.map(_.singleton)) ) /** - * Equivalent to `ReadonlyArray#traverse(ApplicativeSeq)`. + * Equivalent to `ReadonlyArray#traverseWithIndex(ApplicativeSeq)`. * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndexSeq = ( + f: (index: number, a: A) => TaskOption +): ((as: ReadonlyArray) => TaskOption>) => { + const g = traverseReadonlyNonEmptyArrayWithIndexSeq(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + +/** + * @since 2.10.0 + */ +export const traverseArrayWithIndex: ( + f: (index: number, a: A) => TaskOption +) => (as: ReadonlyArray) => TaskOption> = traverseReadonlyArrayWithIndex + +/** + * @since 2.10.0 + */ +export const traverseArray: ( + f: (a: A) => TaskOption +) => (as: ReadonlyArray) => TaskOption> = (f) => traverseReadonlyArrayWithIndex((_, a) => f(a)) + +/** + * @since 2.10.0 + */ +export const sequenceArray: (as: ReadonlyArray>) => TaskOption> = + /*#__PURE__*/ + traverseArray(identity) + +/** + * @since 2.10.0 + */ +export const traverseSeqArrayWithIndex: ( + f: (index: number, a: A) => TaskOption +) => (as: ReadonlyArray) => TaskOption> = traverseReadonlyArrayWithIndexSeq + +/** * @since 2.10.0 */ export const traverseSeqArray: ( f: (a: A) => TaskOption -) => (as: ReadonlyArray) => TaskOption> = (f) => traverseSeqArrayWithIndex((_, a) => f(a)) +) => (as: ReadonlyArray) => TaskOption> = (f) => traverseReadonlyArrayWithIndexSeq((_, a) => f(a)) /** - * Equivalent to `ReadonlyArray#sequence(ApplicativeSeq)`. - * * @since 2.10.0 */ export const sequenceSeqArray: (as: ReadonlyArray>) => TaskOption> = /*#__PURE__*/ traverseSeqArray(identity) + +// ------------------------------------------------------------------------------------- +// deprecated +// ------------------------------------------------------------------------------------- + +// tslint:disable: deprecation diff --git a/src/TaskThese.ts b/src/TaskThese.ts index eb5eb7380..54223ad77 100644 --- a/src/TaskThese.ts +++ b/src/TaskThese.ts @@ -13,20 +13,25 @@ import { } from './FromEither' import { FromIO2, fromIOK as fromIOK_ } from './FromIO' import { FromTask2, fromTaskK as fromTaskK_ } from './FromTask' -import { flow, Lazy, pipe } from './function' +import { FromThese2, fromTheseK as fromTheseK_ } from './FromThese' +import { flow, Lazy, pipe, SK } from './function' import { flap as flap_, Functor2 } from './Functor' import { IO } from './IO' -import { IOEither } from './IOEither' +import { URI as IEURI } from './IOEither' import { Monad2C } from './Monad' import { MonadTask2C } from './MonadTask' +import { NaturalTransformation22 } from './NaturalTransformation' import { Pointed2 } from './Pointed' +import { ReadonlyNonEmptyArray } from './ReadonlyNonEmptyArray' import { Semigroup } from './Semigroup' import * as T from './Task' import * as TH from './These' import * as TT from './TheseT' +import * as _ from './internal' import These = TH.These import Task = T.Task +import { NonEmptyArray } from './NonEmptyArray' // ------------------------------------------------------------------------------------- // model @@ -94,31 +99,41 @@ export const leftIO: (me: IO) => TaskThese = /*#__PURE__*/ flow(T.fromIO, leftTask) +// ------------------------------------------------------------------------------------- +// natural transformations +// ------------------------------------------------------------------------------------- + /** - * @category constructors - * @since 2.4.0 + * @category natural transformations + * @since 2.10.0 */ -export const fromIOEither: (fa: IOEither) => TaskThese = - /*#__PURE__*/ - T.fromIO +export const fromEither: FromEither2['fromEither'] = T.of /** - * @category constructors + * @category natural transformations + * @since 2.11.0 + */ +export const fromThese: FromThese2['fromThese'] = T.of + +/** + * @category natural transformations * @since 2.7.0 */ export const fromIO: FromIO2['fromIO'] = rightIO /** - * @category constructors - * @since 2.7.0 + * @category natural transformations + * @since 2.4.0 */ -export const fromTask: FromTask2['fromTask'] = rightTask +export const fromIOEither: NaturalTransformation22 = + /*#__PURE__*/ + T.fromIO /** - * @category constructors - * @since 2.10.0 + * @category natural transformations + * @since 2.7.0 */ -export const fromEither: FromEither2['fromEither'] = T.of +export const fromTask: FromTask2['fromTask'] = rightTask // ------------------------------------------------------------------------------------- // destructors @@ -385,7 +400,7 @@ export const FromEither: FromEither2 = { } /** - * @category constructors + * @category natural transformations * @since 2.10.0 */ export const fromOption = @@ -408,6 +423,23 @@ export const fromPredicate = /*#__PURE__*/ fromPredicate_(FromEither) +/** + * @category instances + * @since 2.11.0 + */ +export const FromThese: FromThese2 = { + URI, + fromThese +} + +/** + * @category combinators + * @since 2.11.0 + */ +export const fromTheseK = + /*#__PURE__*/ + fromTheseK_(FromThese) + /** * @category instances * @since 2.10.0 @@ -454,6 +486,86 @@ export const toTuple2: (e: Lazy, a: Lazy) => (fa: TaskThese) = /*#__PURE__*/ TT.toTuple2(T.Functor) +// ------------------------------------------------------------------------------------- +// sequence T +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export const ApT: TaskThese = of(_.emptyReadonlyArray) + +// ------------------------------------------------------------------------------------- +// array utils +// ------------------------------------------------------------------------------------- + +/** + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(getApplicative(T.ApplicativePar, S))`. + * + * @since 2.11.0 + */ +export const traverseReadonlyNonEmptyArrayWithIndex = ( + S: Semigroup +): (( + f: (index: number, a: A) => TaskThese +) => (as: ReadonlyNonEmptyArray) => TaskThese>) => { + const g = TH.traverseReadonlyNonEmptyArrayWithIndex(S) + return (f) => flow(T.traverseReadonlyNonEmptyArrayWithIndex(f), T.map(g(SK))) +} + +/** + * Equivalent to `ReadonlyArray#traverseWithIndex(getApplicative(T.ApplicativePar, S))`. + * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndex = (S: Semigroup) => ( + f: (index: number, a: A) => TaskThese +): ((as: ReadonlyArray) => TaskThese>) => { + const g = traverseReadonlyNonEmptyArrayWithIndex(S)(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + +/** + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(getApplicative(T.ApplicativeSeq, S))`. + * + * @since 2.11.0 + */ +export const traverseReadonlyNonEmptyArrayWithIndexSeq = (S: Semigroup) => ( + f: (index: number, a: A) => TaskThese +) => (as: ReadonlyNonEmptyArray): TaskThese> => () => + _.tail(as).reduce>>>( + (acc, a, i) => + acc.then((ebs) => + TH.isLeft(ebs) + ? acc + : f(i + 1, a)().then((eb) => { + if (TH.isLeft(eb)) { + return eb + } + if (TH.isBoth(eb)) { + const right = ebs.right + right.push(eb.right) + return TH.isBoth(ebs) ? TH.both(S.concat(ebs.left, eb.left), right) : TH.both(eb.left, right) + } + ebs.right.push(eb.right) + return ebs + }) + ), + f(0, _.head(as))().then(TH.map(_.singleton)) + ) + +/** + * Equivalent to `ReadonlyArray#traverseWithIndex(getApplicative(T.ApplicativeSeq, S))`. + * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndexSeq = (S: Semigroup) => ( + f: (index: number, a: A) => TaskThese +): ((as: ReadonlyArray) => TaskThese>) => { + const g = traverseReadonlyNonEmptyArrayWithIndexSeq(S)(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + // ------------------------------------------------------------------------------------- // deprecated // ------------------------------------------------------------------------------------- diff --git a/src/These.ts b/src/These.ts index edcae583b..57cfe246e 100644 --- a/src/These.ts +++ b/src/These.ts @@ -27,14 +27,19 @@ import { Either, Left, Right } from './Either' import { Eq, fromEquals } from './Eq' import { Foldable2 } from './Foldable' import { FromEither2, fromOption as fromOption_, fromOptionK as fromOptionK_ } from './FromEither' +import { FromThese2 } from './FromThese' import { identity, Lazy, pipe } from './function' import { flap as flap_, Functor2 } from './Functor' import { HKT } from './HKT' +import * as _ from './internal' import { Monad2C } from './Monad' import { MonadThrow2C } from './MonadThrow' import { Monoid } from './Monoid' -import { isNone, none, Option, some } from './Option' +import { NonEmptyArray } from './NonEmptyArray' +import { Option } from './Option' import { Pointed2 } from './Pointed' +import { Predicate } from './Predicate' +import { ReadonlyNonEmptyArray } from './ReadonlyNonEmptyArray' import { Semigroup } from './Semigroup' import { Show } from './Show' import { PipeableTraverse2, Traversable2 } from './Traversable' @@ -59,6 +64,40 @@ export interface Both { */ export type These = Either | Both +// ------------------------------------------------------------------------------------- +// refinements +// ------------------------------------------------------------------------------------- + +/** + * Returns `true` if the these is an instance of `Left`, `false` otherwise + * + * @category refinements + * @since 2.0.0 + */ +export const isLeft = (fa: These): fa is Left => fa._tag === 'Left' + +/** + * Returns `true` if the these is an instance of `Right`, `false` otherwise + * + * @category refinements + * @since 2.0.0 + */ +export const isRight = (fa: These): fa is Right => fa._tag === 'Right' + +/** + * Returns `true` if the these is an instance of `Both`, `false` otherwise + * + * @category refinements + * @since 2.0.0 + */ +export function isBoth(fa: These): fa is Both { + return fa._tag === 'Both' +} + +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- + /** * @category constructors * @since 2.0.0 @@ -295,7 +334,7 @@ export function getMonad(S: Semigroup): Monad2C & MonadThrow2C(fa: These): Option { - return isLeft(fa) ? some(fa.left) : isRight(fa) ? none : some(fa.left) + return isLeft(fa) ? _.some(fa.left) : isRight(fa) ? _.none : _.some(fa.left) } /** @@ -313,37 +352,7 @@ export function getLeft(fa: These): Option { * @since 2.0.0 */ export function getRight(fa: These): Option { - return isLeft(fa) ? none : isRight(fa) ? some(fa.right) : some(fa.right) -} - -/** - * Returns `true` if the these is an instance of `Left`, `false` otherwise - * - * @category guards - * @since 2.0.0 - */ -export function isLeft(fa: These): fa is Left { - return fa._tag === 'Left' -} - -/** - * Returns `true` if the these is an instance of `Right`, `false` otherwise - * - * @category guards - * @since 2.0.0 - */ -export function isRight(fa: These): fa is Right { - return fa._tag === 'Right' -} - -/** - * Returns `true` if the these is an instance of `Both`, `false` otherwise - * - * @category guards - * @since 2.0.0 - */ -export function isBoth(fa: These): fa is Both { - return fa._tag === 'Both' + return isLeft(fa) ? _.none : isRight(fa) ? _.some(fa.right) : _.some(fa.right) } // TODO: make lazy in v3 @@ -359,7 +368,7 @@ export function isBoth(fa: These): fa is Both { * @since 2.0.0 */ export function leftOrBoth(e: E): (ma: Option) => These { - return (ma) => (isNone(ma) ? left(e) : both(e, ma.value)) + return (ma) => (_.isNone(ma) ? left(e) : both(e, ma.value)) } // TODO: make lazy in v3 @@ -375,7 +384,7 @@ export function leftOrBoth(e: E): (ma: Option) => These { * @since 2.0.0 */ export function rightOrBoth(a: A): (me: Option) => These { - return (me) => (isNone(me) ? right(a) : both(me.value, a)) + return (me) => (_.isNone(me) ? right(a) : both(me.value, a)) } /** @@ -393,7 +402,7 @@ export function rightOrBoth(a: A): (me: Option) => These { * @since 2.0.0 */ export function getLeftOnly(fa: These): Option { - return isLeft(fa) ? some(fa.left) : none + return isLeft(fa) ? _.some(fa.left) : _.none } /** @@ -411,7 +420,7 @@ export function getLeftOnly(fa: These): Option { * @since 2.0.0 */ export function getRightOnly(fa: These): Option { - return isRight(fa) ? some(fa.right) : none + return isRight(fa) ? _.some(fa.right) : _.none } /** @@ -429,15 +438,14 @@ export function getRightOnly(fa: These): Option { * @category constructors * @since 2.0.0 */ -export function fromOptions(fe: Option, fa: Option): Option> { - return isNone(fe) - ? isNone(fa) - ? none - : some(right(fa.value)) - : isNone(fa) - ? some(left(fe.value)) - : some(both(fe.value, fa.value)) -} +export const fromOptions = (fe: Option, fa: Option): Option> => + _.isNone(fe) + ? _.isNone(fa) + ? _.none + : _.some(right(fa.value)) + : _.isNone(fa) + ? _.some(left(fe.value)) + : _.some(both(fe.value, fa.value)) // ------------------------------------------------------------------------------------- // non-pipeables @@ -502,21 +510,21 @@ export const map: (f: (a: A) => B) => (fa: These) => These * @since 2.0.0 */ export const reduce: (b: B, f: (b: B, a: A) => B) => (fa: These) => B = (b, f) => (fa) => - isLeft(fa) ? b : isRight(fa) ? f(b, fa.right) : f(b, fa.right) + isLeft(fa) ? b : f(b, fa.right) /** * @category Foldable * @since 2.0.0 */ export const foldMap: (M: Monoid) => (f: (a: A) => M) => (fa: These) => M = (M) => (f) => (fa) => - isLeft(fa) ? M.empty : isRight(fa) ? f(fa.right) : f(fa.right) + isLeft(fa) ? M.empty : f(fa.right) /** * @category Foldable * @since 2.0.0 */ export const reduceRight: (b: B, f: (a: A, b: B) => B) => (fa: These) => B = (b, f) => (fa) => - isLeft(fa) ? b : isRight(fa) ? f(fa.right, b) : f(fa.right, b) + isLeft(fa) ? b : f(fa.right, b) /** * @since 2.6.3 @@ -601,6 +609,15 @@ export const Bifunctor: Bifunctor2 = { mapLeft: _mapLeft } +/** + * @category instances + * @since 2.11.0 + */ +export const FromThese: FromThese2 = { + URI, + fromThese: identity +} + /** * @category instances * @since 2.7.0 @@ -636,7 +653,7 @@ export const FromEither: FromEither2 = { } /** - * @category constructors + * @category natural transformations * @since 2.10.0 */ export const fromOption = @@ -655,6 +672,18 @@ export const fromOptionK = // utils // ------------------------------------------------------------------------------------- +/** + * @since 2.11.0 + */ +export const elem = (E: Eq) => (a: A) => (ma: These): boolean => + isLeft(ma) ? false : E.equals(a, ma.right) + +/** + * @since 2.11.0 + */ +export const exists = (predicate: Predicate) => (ma: These): boolean => + isLeft(ma) ? false : predicate(ma.right) + /** * @example * import { toTuple2, left, right, both } from 'fp-ts/These' @@ -684,6 +713,61 @@ export const toTuple = (e: E, a: A): ((fa: These) => [E, A]) => () => a ) as any +// ------------------------------------------------------------------------------------- +// sequence T +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export const ApT: These = of(_.emptyReadonlyArray) + +// ------------------------------------------------------------------------------------- +// array utils +// ------------------------------------------------------------------------------------- + +/** + * Equivalent to `ReadonlyNonEmptyArray#traverseWithIndex(getApplicative(S))`. + * + * @since 2.11.0 + */ +export const traverseReadonlyNonEmptyArrayWithIndex = (S: Semigroup) => ( + f: (index: number, a: A) => These +) => (as: ReadonlyNonEmptyArray): These> => { + let e: Option = _.none + const t = f(0, _.head(as)) + if (isLeft(t)) { + return t + } + if (isBoth(t)) { + e = _.some(t.left) + } + const out: NonEmptyArray = [t.right] + for (let i = 1; i < as.length; i++) { + const t = f(i, as[i]) + if (isLeft(t)) { + return t + } + if (isBoth(t)) { + e = _.isNone(e) ? _.some(t.left) : _.some(S.concat(e.value, t.left)) + } + out.push(t.right) + } + return _.isNone(e) ? right(out) : both(e.value, out) +} + +/** + * Equivalent to `ReadonlyArray#traverseWithIndex(getApplicative(S))`. + * + * @since 2.11.0 + */ +export const traverseReadonlyArrayWithIndex = (S: Semigroup) => ( + f: (index: number, a: A) => These +): ((as: ReadonlyArray) => These>) => { + const g = traverseReadonlyNonEmptyArrayWithIndex(S)(f) + return (as) => (_.isNonEmpty(as) ? g(as) : ApT) +} + // ------------------------------------------------------------------------------------- // deprecated // ------------------------------------------------------------------------------------- diff --git a/src/Tree.ts b/src/Tree.ts index f28a29037..2e2a41e39 100644 --- a/src/Tree.ts +++ b/src/Tree.ts @@ -10,6 +10,7 @@ import { Applicative as ApplicativeHKT, Applicative1 } from './Applicative' import { apFirst as apFirst_, Apply1, apS as apS_, apSecond as apSecond_ } from './Apply' import * as A from './Array' +import { bind as bind_, Chain1, chainFirst as chainFirst_ } from './Chain' import { Comonad1 } from './Comonad' import { Eq, fromEquals } from './Eq' import { Extend1 } from './Extend' @@ -17,10 +18,11 @@ import { Foldable1 } from './Foldable' import { identity, pipe } from './function' import { bindTo as bindTo_, flap as flap_, Functor1 } from './Functor' import { HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT' -import { bind as bind_, Chain1, chainFirst as chainFirst_ } from './Chain' +import * as _ from './internal' import { Monad as MonadHKT, Monad1, Monad2, Monad2C, Monad3, Monad3C, Monad4 } from './Monad' import { Monoid } from './Monoid' import { Pointed1 } from './Pointed' +import { Predicate } from './Predicate' import { Show } from './Show' import { PipeableTraverse1, Traversable1 } from './Traversable' @@ -217,20 +219,6 @@ export function unfoldForestM( ) } -// TODO: curry in v3 -/** - * @since 2.0.0 - */ -export function elem(E: Eq): (a: A, fa: Tree) => boolean { - const go = (a: A, fa: Tree): boolean => { - if (E.equals(a, fa.value)) { - return true - } - return fa.forest.some((tree) => go(a, tree)) - } - return go -} - /** * Fold a tree into a "summary" value in depth-first order. * @@ -608,7 +596,7 @@ export const Comonad: Comonad1 = { */ export const Do: Tree<{}> = /*#__PURE__*/ - of({}) + of(_.emptyRecord) /** * @since 2.8.0 @@ -635,6 +623,24 @@ export const apS = /*#__PURE__*/ apS_(Apply) +// ------------------------------------------------------------------------------------- +// utils +// ------------------------------------------------------------------------------------- + +/** + * @since 2.0.0 + */ +export function elem(E: Eq): (a: A, fa: Tree) => boolean { + const go = (a: A, fa: Tree): boolean => E.equals(a, fa.value) || fa.forest.some((tree) => go(a, tree)) + return go +} + +/** + * @since 2.11.0 + */ +export const exists = (predicate: Predicate) => (ma: Tree): boolean => + predicate(ma.value) || ma.forest.some(exists(predicate)) + // ------------------------------------------------------------------------------------- // deprecated // ------------------------------------------------------------------------------------- diff --git a/src/ValidationT.ts b/src/ValidationT.ts index 64fa67a24..b6d30df83 100644 --- a/src/ValidationT.ts +++ b/src/ValidationT.ts @@ -10,6 +10,7 @@ import { import * as E from './Either' import { Lazy } from './function' import { HKT, Kind, Kind2, URIS, URIS2 } from './HKT' +import * as _ from './internal' import { Monad, Monad1, Monad2 } from './Monad' import { Semigroup } from './Semigroup' @@ -99,10 +100,10 @@ export function getValidationM(S: Semigroup, M: Monad): ValidationM< map: A.map, ap: A.ap, of: A.of, - chain: (ma, f) => M.chain(ma, (e) => (E.isLeft(e) ? M.of(E.left(e.left)) : f(e.right))), + chain: (ma, f) => M.chain(ma, (e) => (_.isLeft(e) ? M.of(_.left(e.left)) : f(e.right))), alt: (me, that) => M.chain(me, (e1) => - E.isRight(e1) ? M.of(e1) : M.map(that(), (e2) => (E.isLeft(e2) ? E.left(S.concat(e1.left, e2.left)) : e2)) + _.isRight(e1) ? M.of(e1) : M.map(that(), (e2) => (_.isLeft(e2) ? _.left(S.concat(e1.left, e2.left)) : e2)) ) } } diff --git a/src/Witherable.ts b/src/Witherable.ts index 602686c6d..3584a9dea 100644 --- a/src/Witherable.ts +++ b/src/Witherable.ts @@ -5,13 +5,15 @@ * * @since 2.0.0 */ -import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT' -import { Option } from './Option' -import { Traversable, Traversable1, Traversable2, Traversable2C, Traversable3 } from './Traversable' import { Applicative, Applicative1, Applicative2, Applicative2C, Applicative3, Applicative3C } from './Applicative' -import { Filterable, Filterable1, Filterable2, Filterable2C, Filterable3 } from './Filterable' +import { Compactable, Compactable1, Compactable2, Compactable2C } from './Compactable' import { Either } from './Either' +import { Filterable, Filterable1, Filterable2, Filterable2C, Filterable3 } from './Filterable' +import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from './HKT' +import * as _ from './internal' +import { Option } from './Option' import { Separated } from './Separated' +import { Traversable, Traversable1, Traversable2, Traversable2C, Traversable3 } from './Traversable' // ------------------------------------------------------------------------------------- // model @@ -546,3 +548,95 @@ export interface PipeableWilt3 { f: (a: A) => HKT> ) => (wa: Kind3) => HKT, Kind3>> } + +// ------------------------------------------------------------------------------------- +// defaults +// ------------------------------------------------------------------------------------- + +/** + * Return a `wilt` implementation from `Traversable` and `Compactable`. + * + * @category defaults + * @since 2.11.0 + */ +export function wiltDefault(T: Traversable2C, C: Compactable2): Witherable2C['wilt'] +export function wiltDefault(T: Traversable2, C: Compactable2C): Witherable2C['wilt'] +export function wiltDefault(T: Traversable1, C: Compactable1): Witherable1['wilt'] +export function wiltDefault(T: Traversable, C: Compactable): Witherable['wilt'] +export function wiltDefault(T: Traversable, C: Compactable): Witherable['wilt'] { + return ( + F: Applicative + ): ((wa: HKT, f: (a: A) => HKT>) => HKT, HKT>>) => { + const traverseF = T.traverse(F) + return (wa, f) => F.map(traverseF(wa, f), C.separate) + } +} + +/** + * Return a `wither` implementation from `Traversable` and `Compactable`. + * + * @category defaults + * @since 2.11.0 + */ +export function witherDefault( + T: Traversable2C, + C: Compactable2 +): Witherable2C['wither'] +export function witherDefault( + T: Traversable2, + C: Compactable2C +): Witherable2C['wither'] +export function witherDefault(T: Traversable1, C: Compactable1): Witherable1['wither'] +export function witherDefault(T: Traversable, C: Compactable): Witherable['wither'] +export function witherDefault(T: Traversable, C: Compactable): Witherable['wither'] { + return (F: Applicative): ((wa: HKT, f: (a: A) => HKT>) => HKT>) => { + const traverseF = T.traverse(F) + return (wa, f) => F.map(traverseF(wa, f), C.compact) + } +} + +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- + +/** + * @since 2.11.0 + */ +export interface FilterE1 { + (F: Applicative3): ( + predicate: (a: A) => Kind3 + ) => (ga: Kind) => Kind3> + (F: Applicative3C): ( + predicate: (a: A) => Kind3 + ) => (ga: Kind) => Kind3> + (F: Applicative2): ( + predicate: (a: A) => Kind2 + ) => (ga: Kind) => Kind2> + (F: Applicative2C): ( + predicate: (a: A) => Kind2 + ) => (ga: Kind) => Kind2> + (F: Applicative1): ( + predicate: (a: A) => Kind + ) => (ga: Kind) => Kind> + (F: Applicative): (predicate: (a: A) => HKT) => (ga: Kind) => HKT> +} + +/** + * Filter values inside a `F` context. + * + * See `ReadonlyArray`'s `filterE` for an example of usage. + * + * @since 2.11.0 + */ +export function filterE(W: Witherable1): FilterE1 +export function filterE( + W: Witherable +): (F: Applicative) => (predicate: (a: A) => HKT) => (ga: HKT) => HKT> +export function filterE( + W: Witherable +): (F: Applicative) => (predicate: (a: A) => HKT) => (ga: HKT) => HKT> { + return (F) => { + const witherF = W.wither(F) + return (predicate) => (ga) => witherF(ga, (a) => F.map(predicate(a), (b) => (b ? _.some(a) : _.none))) + } +} diff --git a/src/Zero.ts b/src/Zero.ts new file mode 100644 index 000000000..97cc73670 --- /dev/null +++ b/src/Zero.ts @@ -0,0 +1,93 @@ +/** + * @since 2.11.0 + */ +import { HKT, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT' +import { Pointed, Pointed1, Pointed2, Pointed2C, Pointed3, Pointed3C, Pointed4 } from './Pointed' + +// ------------------------------------------------------------------------------------- +// model +// ------------------------------------------------------------------------------------- + +/** + * @category type classes + * @since 2.11.0 + */ +export interface Zero { + readonly URI: F + readonly zero: () => HKT +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface Zero1 { + readonly URI: F + readonly zero: () => Kind +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface Zero2 { + readonly URI: F + readonly zero: () => Kind2 +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface Zero2C { + readonly URI: F + readonly _E: E + readonly zero: () => Kind2 +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface Zero3 { + readonly URI: F + readonly zero: () => Kind3 +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface Zero3C { + readonly URI: F + readonly _E: E + readonly zero: () => Kind3 +} + +/** + * @category type classes + * @since 2.11.0 + */ +export interface Zero4 { + readonly URI: F + readonly zero: () => Kind4 +} + +// ------------------------------------------------------------------------------------- +// constructors +// ------------------------------------------------------------------------------------- + +/** + * @category constructors + * @since 2.11.0 + */ +export function guard(F: Zero4, P: Pointed4): (b: boolean) => Kind4 +export function guard(F: Zero3, P: Pointed3): (b: boolean) => Kind3 +export function guard(F: Zero3C, P: Pointed3C): (b: boolean) => Kind3 +export function guard(F: Zero2, P: Pointed2): (b: boolean) => Kind2 +export function guard(F: Zero2C, P: Pointed2C): (b: boolean) => Kind2 +export function guard(F: Zero1, P: Pointed1): (b: boolean) => Kind +export function guard(F: Zero, P: Pointed): (b: boolean) => HKT +export function guard(F: Zero, P: Pointed): (b: boolean) => HKT { + return (b) => (b ? P.of(undefined) : F.zero()) +} diff --git a/src/boolean.ts b/src/boolean.ts index 7b22a4405..8411912b8 100644 --- a/src/boolean.ts +++ b/src/boolean.ts @@ -3,12 +3,23 @@ */ import * as BA from './BooleanAlgebra' import * as E from './Eq' -import { Semigroup, semigroupAll, semigroupAny } from './Semigroup' import { Lazy } from './function' -import { Monoid, monoidAll, monoidAny } from './Monoid' +import { Monoid } from './Monoid' import * as O from './Ord' +import { Refinement } from './Refinement' +import { Semigroup } from './Semigroup' import * as S from './Show' +// ------------------------------------------------------------------------------------- +// refinements +// ------------------------------------------------------------------------------------- + +/** + * @category refinements + * @since 2.11.0 + */ +export const isBoolean: Refinement = (u: unknown): u is boolean => typeof u === 'boolean' + // ------------------------------------------------------------------------------------- // destructors // ------------------------------------------------------------------------------------- @@ -69,15 +80,22 @@ export const fold = match * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const Eq: E.Eq = E.eqBoolean +export const Eq: E.Eq = { + equals: (first, second) => first === second +} /** * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const BooleanAlgebra: BA.BooleanAlgebra = BA.booleanAlgebraBoolean +export const BooleanAlgebra: BA.BooleanAlgebra = { + meet: (first, second) => first && second, + join: (first, second) => first || second, + zero: false, + one: true, + implies: (first, second) => !first || second, + not: (b) => !b +} /** * `boolean` semigroup under conjunction. @@ -91,8 +109,9 @@ export const BooleanAlgebra: BA.BooleanAlgebra = BA.booleanAlgebraBoole * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const SemigroupAll: Semigroup = semigroupAll +export const SemigroupAll: Semigroup = { + concat: (first, second) => first && second +} /** * `boolean` semigroup under disjunction. @@ -107,8 +126,9 @@ export const SemigroupAll: Semigroup = semigroupAll * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const SemigroupAny: Semigroup = semigroupAny +export const SemigroupAny: Semigroup = { + concat: (first, second) => first || second +} /** * `boolean` monoid under conjunction. @@ -124,8 +144,10 @@ export const SemigroupAny: Semigroup = semigroupAny * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const MonoidAll: Monoid = monoidAll +export const MonoidAll: Monoid = { + concat: SemigroupAll.concat, + empty: true +} /** * `boolean` monoid under disjunction. @@ -142,19 +164,24 @@ export const MonoidAll: Monoid = monoidAll * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const MonoidAny: Monoid = monoidAny +export const MonoidAny: Monoid = { + concat: SemigroupAny.concat, + empty: false +} /** * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const Ord: O.Ord = O.ordBoolean +export const Ord: O.Ord = { + equals: Eq.equals, + compare: (first, second) => (first < second ? -1 : first > second ? 1 : 0) +} /** * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const Show: S.Show = S.showBoolean +export const Show: S.Show = { + show: (b) => JSON.stringify(b) +} diff --git a/src/function.ts b/src/function.ts index 5e114f355..db756f123 100644 --- a/src/function.ts +++ b/src/function.ts @@ -55,7 +55,8 @@ export const getSemigroup = (S: Semigroup) => (): Semigroup<(a: * Unary functions form a monoid as long as you can provide a monoid for the codomain. * * @example - * import { Predicate, getMonoid } from 'fp-ts/function' + * import { Predicate } from 'fp-ts/Predicate' + * import { getMonoid } from 'fp-ts/function' * import * as B from 'fp-ts/boolean' * * const f: Predicate = (n) => n <= 2 @@ -108,21 +109,15 @@ export const getRing = (R: Ring): Ring<(a: A) => B> => { } } -/** - * Endomorphism form a monoid where the `empty` value is the identity function. - * - * @category instances - * @since 2.10.0 - */ -export const getEndomorphismMonoid = (): Monoid> => ({ - concat: (x, y) => (a) => y(x(a)), - empty: identity -}) - // ------------------------------------------------------------------------------------- // utils // ------------------------------------------------------------------------------------- +/** + * @since 2.11.0 + */ +export const apply = (a: A) => (f: (a: A) => B): B => f(a) + /** * A *thunk* * @@ -132,27 +127,6 @@ export interface Lazy { (): A } -/** - * @since 2.0.0 - */ -export interface Predicate { - (a: A): boolean -} - -/** - * @since 2.0.0 - */ -export interface Refinement { - (a: A): a is B -} - -/** - * @since 2.0.0 - */ -export interface Endomorphism { - (a: A): A -} - /** * @example * import { FunctionN } from 'fp-ts/function' @@ -177,13 +151,6 @@ export function identity(a: A): A { */ export const unsafeCoerce: (a: A) => B = identity as any -/** - * @since 2.0.0 - */ -export function not(predicate: Predicate): Predicate { - return (a) => !predicate(a) -} - /** * @since 2.0.0 */ @@ -748,3 +715,66 @@ export function pipe( * @since 2.7.0 */ export const hole: () => T = absurd as any + +/** + * @since 2.11.0 + */ +export const SK = (_: A, b: B): B => b + +// ------------------------------------------------------------------------------------- +// deprecated +// ------------------------------------------------------------------------------------- + +// tslint:disable: deprecation + +/** + * Use `Refinement` module instead. + * + * @since 2.0.0 + * @deprecated + */ +export interface Refinement { + (a: A): a is B +} + +/** + * Use `Predicate` module instead. + * + * @since 2.0.0 + * @deprecated + */ +export interface Predicate { + (a: A): boolean +} + +/** + * Use `Predicate` module instead. + * + * @since 2.0.0 + * @deprecated + */ +export function not(predicate: Predicate): Predicate { + return (a) => !predicate(a) +} + +/** + * Use `Endomorphism` module instead. + * + * @since 2.0.0 + * @deprecated + */ +export interface Endomorphism { + (a: A): A +} + +/** + * Use `Endomorphism` module instead. + * + * @category instances + * @since 2.10.0 + * @deprecated + */ +export const getEndomorphismMonoid = (): Monoid> => ({ + concat: (first, second) => flow(first, second), + empty: identity +}) diff --git a/src/index.ts b/src/index.ts index 85846f2af..6d1fb9f91 100644 --- a/src/index.ts +++ b/src/index.ts @@ -28,6 +28,7 @@ import * as date from './Date' import * as distributiveLattice from './DistributiveLattice' import * as either from './Either' import * as eitherT from './EitherT' +import * as endomorphism from './Endomorphism' import * as eq from './Eq' import * as extend from './Extend' import * as field from './Field' @@ -37,7 +38,10 @@ import * as foldable from './Foldable' import * as foldableWithIndex from './FoldableWithIndex' import * as fromEither from './FromEither' import * as fromIO from './FromIO' +import * as fromReader from './FromReader' +import * as fromState from './FromState' import * as fromTask from './FromTask' +import * as fromThese from './FromThese' import * as function_ from './function' import * as functor from './Functor' import * as functorWithIndex from './FunctorWithIndex' @@ -60,6 +64,7 @@ import * as monadIO from './MonadIO' import * as monadTask from './MonadTask' import * as monadThrow from './MonadThrow' import * as monoid from './Monoid' +import * as naturalTransformation from './NaturalTransformation' import * as nonEmptyArray from './NonEmptyArray' import * as number from './number' import * as option from './Option' @@ -68,6 +73,7 @@ import * as ord from './Ord' import * as ordering from './Ordering' import * as pipeable from './pipeable' import * as pointed from './Pointed' +import * as predicate from './Predicate' import * as profunctor from './Profunctor' import * as random from './Random' import * as reader from './Reader' @@ -82,6 +88,7 @@ import * as readonlyRecord from './ReadonlyRecord' import * as readonlySet from './ReadonlySet' import * as readonlyTuple from './ReadonlyTuple' import * as record from './Record' +import * as refinement from './Refinement' import * as ring from './Ring' import * as semigroup from './Semigroup' import * as semigroupoid from './Semigroupoid' @@ -109,9 +116,11 @@ import * as tree from './Tree' import * as tuple from './Tuple' import * as unfoldable from './Unfoldable' import * as validationT from './ValidationT' +import * as void_ from './void' import * as witherable from './Witherable' import * as writer from './Writer' import * as writerT from './WriterT' +import * as zero from './Zero' export { /** * @since 2.0.0 @@ -217,6 +226,10 @@ export { * @since 2.0.0 */ eitherT, + /** + * @since 2.11.0 + */ + endomorphism, /** * @since 2.0.0 */ @@ -249,10 +262,22 @@ export { * @since 2.10.0 */ fromIO, + /** + * @since 2.11.0 + */ + fromReader, + /** + * @since 2.11.0 + */ + fromState, /** * @since 2.10.0 */ fromTask, + /** + * @since 2.11.0 + */ + fromThese, /** * @since 2.0.0 */ @@ -341,6 +366,10 @@ export { * @since 2.0.0 */ monoid, + /** + * @since 2.11.0 + */ + naturalTransformation, /** * @since 2.0.0 */ @@ -349,10 +378,6 @@ export { * @since 2.10.0 */ number, - /** - * @since 2.10.0 - */ - struct, /** * @since 2.0.0 */ @@ -377,6 +402,10 @@ export { * @since 2.10.0 */ pointed, + /** + * @since 2.11.0 + */ + predicate, /** * @since 2.0.0 */ @@ -433,6 +462,10 @@ export { * @since 2.0.0 */ record, + /** + * @since 2.11.0 + */ + refinement, /** * @since 2.0.0 */ @@ -489,6 +522,10 @@ export { * @since 2.0.0 */ strong, + /** + * @since 2.10.0 + */ + struct, /** * @since 2.0.0 */ @@ -541,6 +578,10 @@ export { * @since 2.0.0 */ validationT, + /** + * @since 2.11.0 + */ + void_ as void, /** * @since 2.0.0 */ @@ -552,5 +593,9 @@ export { /** * @since 2.4.0 */ - writerT + writerT, + /** + * @since 2.11.0 + */ + zero } diff --git a/src/internal.ts b/src/internal.ts index 61c4fbbd9..0f70718e7 100644 --- a/src/internal.ts +++ b/src/internal.ts @@ -1,24 +1,68 @@ /** * @since 2.10.0 */ -import { Either, Left } from './Either' +import { Either, Left, Right } from './Either' import { NonEmptyArray } from './NonEmptyArray' -import { Option, Some } from './Option' +import { None, Option, Some } from './Option' import { ReadonlyNonEmptyArray } from './ReadonlyNonEmptyArray' // ------------------------------------------------------------------------------------- // Option // ------------------------------------------------------------------------------------- +/** @internal */ +export const isNone = (fa: Option): fa is None => fa._tag === 'None' + /** @internal */ export const isSome = (fa: Option): fa is Some => fa._tag === 'Some' +/** @internal */ +export const none: Option = { _tag: 'None' } + +/** @internal */ +export const some = (a: A): Option => ({ _tag: 'Some', value: a }) + // ------------------------------------------------------------------------------------- // Either // ------------------------------------------------------------------------------------- /** @internal */ -export const isLeft = (ma: Either): ma is Left => ma._tag === 'Left' +export const isLeft = (ma: Either): ma is Left => ma._tag === 'Left' + +/** @internal */ +export const isRight = (ma: Either): ma is Right => ma._tag === 'Right' + +/** @internal */ +export const left = (e: E): Either => ({ _tag: 'Left', left: e }) + +/** @internal */ +export const right = (a: A): Either => ({ _tag: 'Right', right: a }) + +// ------------------------------------------------------------------------------------- +// ReadonlyNonEmptyArray +// ------------------------------------------------------------------------------------- + +/** @internal */ +export const singleton = (a: A): NonEmptyArray => [a] + +/** @internal */ +export const isNonEmpty = (as: ReadonlyArray): as is ReadonlyNonEmptyArray => as.length > 0 + +/** @internal */ +export const head = (as: ReadonlyNonEmptyArray): A => as[0] + +/** @internal */ +export const tail = (as: ReadonlyNonEmptyArray): ReadonlyArray => as.slice(1) + +// ------------------------------------------------------------------------------------- +// empty +// ------------------------------------------------------------------------------------- + +/** @internal */ +export const emptyReadonlyArray: readonly [] = [] + +/** @internal */ +export const emptyRecord: {} = {} // ------------------------------------------------------------------------------------- // Record diff --git a/src/number.ts b/src/number.ts index c920e9991..5ed8aef9c 100644 --- a/src/number.ts +++ b/src/number.ts @@ -4,45 +4,70 @@ import * as B from './Bounded' import * as E from './Eq' import * as F from './Field' +import { Magma } from './Magma' +import { Monoid } from './Monoid' import * as O from './Ord' +import { Refinement } from './Refinement' +import { Semigroup } from './Semigroup' import * as S from './Show' -import { Semigroup, semigroupProduct, semigroupSum } from './Semigroup' -import { Monoid, monoidProduct, monoidSum } from './Monoid' + +// ------------------------------------------------------------------------------------- +// refinements +// ------------------------------------------------------------------------------------- + +/** + * @category refinements + * @since 2.11.0 + */ +export const isNumber: Refinement = (u: unknown): u is number => typeof u === 'number' + +// ------------------------------------------------------------------------------------- +// instances +// ------------------------------------------------------------------------------------- /** * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const Eq: E.Eq = E.eqNumber +export const Eq: E.Eq = { + equals: (first, second) => first === second +} /** * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const Ord: O.Ord = O.ordNumber +export const Ord: O.Ord = { + equals: Eq.equals, + compare: (first, second) => (first < second ? -1 : first > second ? 1 : 0) +} /** * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const Bounded: B.Bounded = B.boundedNumber +export const Bounded: B.Bounded = { + equals: Eq.equals, + compare: Ord.compare, + top: Infinity, + bottom: -Infinity +} /** * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const Field: F.Field = F.fieldNumber +export const Show: S.Show = { + show: (n) => JSON.stringify(n) +} /** * @category instances - * @since 2.10.0 + * @since 2.11.0 */ -// tslint:disable-next-line: deprecation -export const Show: S.Show = S.showNumber +export const MagmaSub: Magma = { + concat: (first, second) => first - second +} /** * `number` semigroup under addition. @@ -55,8 +80,9 @@ export const Show: S.Show = S.showNumber * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const SemigroupSum: Semigroup = semigroupSum +export const SemigroupSum: Semigroup = { + concat: (first, second) => first + second +} /** * `number` semigroup under multiplication. @@ -69,8 +95,9 @@ export const SemigroupSum: Semigroup = semigroupSum * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const SemigroupProduct: Semigroup = semigroupProduct +export const SemigroupProduct: Semigroup = { + concat: (first, second) => first * second +} /** * `number` monoid under addition. @@ -85,8 +112,10 @@ export const SemigroupProduct: Semigroup = semigroupProduct * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const MonoidSum: Monoid = monoidSum +export const MonoidSum: Monoid = { + concat: SemigroupSum.concat, + empty: 0 +} /** * `number` monoid under multiplication. @@ -101,5 +130,22 @@ export const MonoidSum: Monoid = monoidSum * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const MonoidProduct: Monoid = monoidProduct +export const MonoidProduct: Monoid = { + concat: SemigroupProduct.concat, + empty: 1 +} + +/** + * @category instances + * @since 2.10.0 + */ +export const Field: F.Field = { + add: SemigroupSum.concat, + zero: 0, + mul: SemigroupProduct.concat, + one: 1, + sub: MagmaSub.concat, + degree: (_) => 1, + div: (first, second) => first / second, + mod: (first, second) => first % second +} diff --git a/src/string.ts b/src/string.ts index eb3f08cb7..14196a414 100644 --- a/src/string.ts +++ b/src/string.ts @@ -6,17 +6,26 @@ import * as M from './Monoid' import * as S from './Semigroup' import * as O from './Ord' import * as Sh from './Show' +import { Refinement } from './Refinement' +import { ReadonlyNonEmptyArray, isNonEmpty } from './ReadonlyNonEmptyArray' // ------------------------------------------------------------------------------------- // instances // ------------------------------------------------------------------------------------- /** + * @example + * import * as S from 'fp-ts/string' + * + * assert.deepStrictEqual(S.Eq.equals('a', 'a'), true) + * assert.deepStrictEqual(S.Eq.equals('a', 'b'), false) + * * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const Eq: E.Eq = E.eqString +export const Eq: E.Eq = { + equals: (first, second) => first === second +} /** * `string` semigroup under concatenation. @@ -29,8 +38,9 @@ export const Eq: E.Eq = E.eqString * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const Semigroup: S.Semigroup = S.semigroupString +export const Semigroup: S.Semigroup = { + concat: (first, second) => first + second +} /** * `string` monoid under concatenation. @@ -41,26 +51,149 @@ export const Semigroup: S.Semigroup = S.semigroupString * import * as S from 'fp-ts/string' * * assert.deepStrictEqual(S.Monoid.concat('a', 'b'), 'ab') + * assert.deepStrictEqual(S.Monoid.concat('a', S.Monoid.empty), 'a') * * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const Monoid: M.Monoid = M.monoidString +export const Monoid: M.Monoid = { + concat: Semigroup.concat, + empty: '' +} /** + * @example + * import * as S from 'fp-ts/string' + * + * assert.deepStrictEqual(S.Ord.compare('a', 'a'), 0) + * assert.deepStrictEqual(S.Ord.compare('a', 'b'), -1) + * assert.deepStrictEqual(S.Ord.compare('b', 'a'), 1) + * * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const Ord: O.Ord = O.ordString +export const Ord: O.Ord = { + equals: Eq.equals, + compare: (first, second) => (first < second ? -1 : first > second ? 1 : 0) +} /** + * @example + * import * as S from 'fp-ts/string' + * + * assert.deepStrictEqual(S.Show.show('a'), '"a"') + * * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const Show: Sh.Show = Sh.showString +export const Show: Sh.Show = { + show: (s) => JSON.stringify(s) +} + +// ------------------------------------------------------------------------------------- +// refinements +// ------------------------------------------------------------------------------------- + +/** + * @example + * import * as S from 'fp-ts/string' + * + * assert.deepStrictEqual(S.isString('a'), true) + * assert.deepStrictEqual(S.isString(1), false) + * + * @category refinements + * @since 2.11.0 + */ +export const isString: Refinement = (u: unknown): u is string => typeof u === 'string' + +// ------------------------------------------------------------------------------------- +// combinators +// ------------------------------------------------------------------------------------- + +/** + * @example + * import * as S from 'fp-ts/string' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual(pipe('a', S.toUpperCase), 'A') + * + * @category combinators + * @since 2.11.0 + */ +export const toUpperCase = (s: string): string => s.toUpperCase() + +/** + * @example + * import * as S from 'fp-ts/string' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual(pipe('A', S.toLowerCase), 'a') + * + * @category combinators + * @since 2.11.0 + */ +export const toLowerCase = (s: string): string => s.toLowerCase() + +/** + * @example + * import * as S from 'fp-ts/string' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual(pipe('abc', S.replace('b', 'd')), 'adc') + * + * @category combinators + * @since 2.11.0 + */ +export const replace = (searchValue: string | RegExp, replaceValue: string) => (s: string): string => + s.replace(searchValue, replaceValue) + +/** + * @example + * import * as S from 'fp-ts/string' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual(pipe(' a ', S.trim), 'a') + * + * @category combinators + * @since 2.11.0 + */ +export const trim = (s: string): string => s.trim() + +/** + * @example + * import * as S from 'fp-ts/string' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual(pipe(' a ', S.trimLeft), 'a ') + * + * @category combinators + * @since 2.11.0 + */ +export const trimLeft = (s: string): string => s.trimLeft() + +/** + * @example + * import * as S from 'fp-ts/string' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual(pipe(' a ', S.trimRight), ' a') + * + * @category combinators + * @since 2.11.0 + */ +export const trimRight = (s: string): string => s.trimRight() + +/** + * @example + * import * as S from 'fp-ts/string' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual(pipe('abcd', S.slice(1, 3)), 'bc') + * + * @category combinators + * @since 2.11.0 + */ +export const slice = (start: number, end: number) => (s: string): string => s.slice(start, end) // ------------------------------------------------------------------------------------- // utils @@ -76,6 +209,13 @@ export const empty: string = '' /** * Test whether a `string` is empty. * + * @example + * import * as S from 'fp-ts/string' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual(pipe('', S.isEmpty), true) + * assert.deepStrictEqual(pipe('a', S.isEmpty), false) + * * @since 2.10.0 */ export const isEmpty = (s: string): boolean => s.length === 0 @@ -83,6 +223,66 @@ export const isEmpty = (s: string): boolean => s.length === 0 /** * Calculate the number of characters in a `string`. * + * @example + * import * as S from 'fp-ts/string' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual(pipe('abc', S.size), 3) + * * @since 2.10.0 */ export const size = (s: string): number => s.length + +/** + * @example + * import * as S from 'fp-ts/string' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual(pipe('abc', S.split('')), ['a', 'b', 'c']) + * assert.deepStrictEqual(pipe('', S.split('')), ['']) + * + * @since 2.11.0 + */ +export const split = (separator: string | RegExp) => (s: string): ReadonlyNonEmptyArray => { + const out = s.split(separator) + return isNonEmpty(out) ? out : [s] +} + +/** + * @example + * import * as S from 'fp-ts/string' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual(pipe('abc', S.includes('b')), true) + * assert.deepStrictEqual(pipe('abc', S.includes('d')), false) + * + * @since 2.11.0 + */ +export const includes = (searchString: string, position?: number) => (s: string): boolean => + s.includes(searchString, position) + +/** + * @example + * import * as S from 'fp-ts/string' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual(pipe('abc', S.startsWith('a')), true) + * assert.deepStrictEqual(pipe('bc', S.startsWith('a')), false) + * + * @since 2.11.0 + */ +export const startsWith = (searchString: string, position?: number) => (s: string): boolean => + s.startsWith(searchString, position) + +/** + * @example + * import * as S from 'fp-ts/string' + * import { pipe } from 'fp-ts/function' + * + * assert.deepStrictEqual(pipe('abc', S.endsWith('c')), true) + * assert.deepStrictEqual(pipe('ab', S.endsWith('c')), false) + * + * @since 2.11.0 + */ +export const endsWith = (searchString: string, position?: number) => (s: string): boolean => + s.endsWith(searchString, position) diff --git a/src/struct.ts b/src/struct.ts index 8dde2104a..c9c5050a7 100644 --- a/src/struct.ts +++ b/src/struct.ts @@ -1,7 +1,8 @@ /** * @since 2.10.0 */ -import { getObjectSemigroup, Semigroup } from './Semigroup' +import * as _ from './internal' +import { Semigroup } from './Semigroup' // ------------------------------------------------------------------------------------- // instances @@ -24,5 +25,42 @@ import { getObjectSemigroup, Semigroup } from './Semigroup' * @category instances * @since 2.10.0 */ -// tslint:disable-next-line: deprecation -export const getAssignSemigroup: () => Semigroup = getObjectSemigroup +export const getAssignSemigroup = (): Semigroup => ({ + concat: (first, second) => Object.assign({}, first, second) +}) + +// ------------------------------------------------------------------------------------- +// utils +// ------------------------------------------------------------------------------------- + +/** + * Creates a new object by recursively evolving a shallow copy of `a`, according to the `transformation` functions. + * + * @example + * import { pipe } from 'fp-ts/function' + * import { evolve } from 'fp-ts/struct' + * + * assert.deepStrictEqual( + * pipe( + * { a: 'a', b: 1 }, + * evolve({ + * a: (a) => a.length, + * b: (b) => b * 2 + * }) + * ), + * { a: 1, b: 2 } + * ) + * + * @since 2.11.0 + */ +export const evolve = unknown }>(transformations: F) => ( + a: A +): { [K in keyof F]: ReturnType } => { + const out: Record = {} + for (const k in a) { + if (_.hasOwnProperty.call(a, k)) { + out[k] = transformations[k](a[k]) + } + } + return out as any +} diff --git a/src/void.ts b/src/void.ts new file mode 100644 index 000000000..02f0e3f88 --- /dev/null +++ b/src/void.ts @@ -0,0 +1,24 @@ +/** + * @since 2.11.0 + */ +import * as M from './Monoid' +import * as Se from './Semigroup' + +// ------------------------------------------------------------------------------------- +// instances +// ------------------------------------------------------------------------------------- + +/** + * @category instances + * @since 2.11.0 + */ +export const Semigroup: Se.Semigroup = Se.constant(undefined) + +/** + * @category instances + * @since 2.11.0 + */ +export const Monoid: M.Monoid = { + concat: Semigroup.concat, + empty: undefined +} diff --git a/test/Alternative.ts b/test/Alternative.ts new file mode 100644 index 000000000..6548595f8 --- /dev/null +++ b/test/Alternative.ts @@ -0,0 +1,12 @@ +import * as _ from '../src/Alternative' +import * as O from '../src/Option' +import * as U from './util' + +describe('Alternative', () => { + it('altAll', () => { + const altAll = _.altAll(O.Alternative) + U.deepStrictEqual(altAll([]), O.none) + U.deepStrictEqual(altAll([O.none]), O.none) + U.deepStrictEqual(altAll([O.none, O.some(1)]), O.some(1)) + }) +}) diff --git a/test/Array.ts b/test/Array.ts index dc4f8abf2..bb01e10ef 100644 --- a/test/Array.ts +++ b/test/Array.ts @@ -4,11 +4,13 @@ import * as _ from '../src/Array' import * as B from '../src/boolean' import * as E from '../src/Either' import * as Eq from '../src/Eq' -import { identity, pipe, Predicate, tuple } from '../src/function' +import { identity, pipe, tuple } from '../src/function' import * as M from '../src/Monoid' import * as N from '../src/number' import * as O from '../src/Option' import * as Ord from '../src/Ord' +import { Predicate } from '../src/Predicate' +import { Refinement } from '../src/Refinement' import { separated } from '../src/Separated' import * as S from '../src/string' import * as T from '../src/Task' @@ -973,6 +975,16 @@ describe('Array', () => { }) }) + it('prepend', () => { + U.deepStrictEqual(pipe(['a', 'b'], _.prepend('c')), ['c', 'a', 'b']) + U.deepStrictEqual(pipe(['a', 'b'], _.prependW(3)), [3, 'a', 'b']) + }) + + it('append', () => { + U.deepStrictEqual(pipe(['a', 'b'], _.append('c')), ['a', 'b', 'c']) + U.deepStrictEqual(pipe(['a', 'b'], _.appendW(3)), ['a', 'b', 3]) + }) + it('makeBy', () => { U.deepStrictEqual(_.makeBy(5, U.double), [0, 2, 4, 6, 8]) U.deepStrictEqual(_.makeBy(0, U.double), []) @@ -980,14 +992,22 @@ describe('Array', () => { }) it('range', () => { + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(0, 0), [0]) + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(0, 1), [0, 1]) + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(1, 5), [1, 2, 3, 4, 5]) + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(10, 15), [10, 11, 12, 13, 14, 15]) + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(-1, 0), [-1, 0]) + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(-5, -1), [-5, -4, -3, -2, -1]) // out of bound + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(2, 1), [2]) + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(-1, -2), [-1]) }) @@ -1069,6 +1089,32 @@ describe('Array', () => { U.deepStrictEqual(pipe([1, 2], _.difference(N.Eq)([1, 2])), []) }) + it('getUnionMonoid', () => { + const concat = _.getUnionMonoid(N.Eq).concat + const two: Array = [1, 2] + U.deepStrictEqual(concat(two, [3, 4]), [1, 2, 3, 4]) + U.deepStrictEqual(concat(two, [2, 3]), [1, 2, 3]) + U.deepStrictEqual(concat(two, [1, 2]), [1, 2]) + + U.deepStrictEqual(concat(two, []), two) + U.deepStrictEqual(concat([], two), two) + U.deepStrictEqual(concat([], []), []) + }) + + it('getIntersectionSemigroup', () => { + const concat = _.getIntersectionSemigroup(N.Eq).concat + U.deepStrictEqual(concat([1, 2], [3, 4]), []) + U.deepStrictEqual(concat([1, 2], [2, 3]), [2]) + U.deepStrictEqual(concat([1, 2], [1, 2]), [1, 2]) + }) + + it('getDifferenceMagma', () => { + const concat = _.getDifferenceMagma(N.Eq).concat + U.deepStrictEqual(concat([1, 2], [3, 4]), [1, 2]) + U.deepStrictEqual(concat([1, 2], [2, 3]), [1]) + U.deepStrictEqual(concat([1, 2], [1, 2]), []) + }) + it('should be safe when calling map with a binary function', () => { interface Foo { readonly bar: () => number @@ -1105,4 +1151,52 @@ describe('Array', () => { it('copy', () => { U.deepStrictEqual(pipe([1, 2, 3], _.copy), [1, 2, 3]) }) + + describe('fromPredicate', () => { + it('can create an array from a Refinement', () => { + const refinement: Refinement = (a): a is string => typeof a === 'string' + U.deepStrictEqual(_.fromPredicate(refinement)('hello'), ['hello']) + U.deepStrictEqual(_.fromPredicate(refinement)(null), []) + }) + + it('can create an array from a Predicate', () => { + const predicate = (a: string) => a.length > 0 + U.deepStrictEqual(_.fromPredicate(predicate)('hi'), ['hi']) + U.deepStrictEqual(_.fromPredicate(predicate)(''), []) + }) + }) + + it('fromOption', () => { + U.deepStrictEqual(_.fromOption(O.some('hello')), ['hello']) + U.deepStrictEqual(_.fromOption(O.none), []) + }) + + it('fromEither', () => { + U.deepStrictEqual(_.fromEither(E.right(1)), [1]) + U.deepStrictEqual(_.fromEither(E.left('a')), []) + }) + + it('match', () => { + const f = _.match( + () => 'empty', + (as) => `nonEmpty ${as.length}` + ) + U.deepStrictEqual(pipe([], f), 'empty') + U.deepStrictEqual(pipe([1, 2, 3], f), 'nonEmpty 3') + }) + + it('concatW', () => { + U.deepStrictEqual(pipe([1], _.concatW(['a'])), [1, 'a']) + const as = [1, 2, 3] + const empty: Array = [] + U.deepStrictEqual(pipe(empty, _.concatW(as)), as) + U.deepStrictEqual(pipe(as, _.concatW(empty)), as) + }) + + it('fromOptionK', () => { + const f = (n: number) => (n > 0 ? O.some(n) : O.none) + const g = _.fromOptionK(f) + U.deepStrictEqual(g(0), []) + U.deepStrictEqual(g(1), [1]) + }) }) diff --git a/test/BooleanAlgebra.ts b/test/BooleanAlgebra.ts index 91c3d160c..d0cba401b 100644 --- a/test/BooleanAlgebra.ts +++ b/test/BooleanAlgebra.ts @@ -3,6 +3,29 @@ import * as _ from '../src/BooleanAlgebra' import * as B from '../src/boolean' describe('BooleanAlgebra', () => { + it('booleanAlgebraBoolean', () => { + // tslint:disable-next-line: deprecation + const BA = _.booleanAlgebraBoolean + U.deepStrictEqual(BA.implies(true, true), true) + U.deepStrictEqual(BA.implies(true, false), false) + U.deepStrictEqual(BA.implies(false, true), true) + U.deepStrictEqual(BA.implies(false, false), true) + + U.deepStrictEqual(BA.join(true, true), true) + U.deepStrictEqual(BA.join(true, false), true) + U.deepStrictEqual(BA.join(false, true), true) + U.deepStrictEqual(BA.join(false, false), false) + + U.deepStrictEqual(BA.meet(true, true), true) + U.deepStrictEqual(BA.meet(true, false), false) + + U.deepStrictEqual(BA.not(true), false) + U.deepStrictEqual(BA.not(false), true) + + U.deepStrictEqual(BA.one, true) + U.deepStrictEqual(BA.zero, false) + }) + it('booleanAlgebraVoid', () => { const BA = _.booleanAlgebraVoid U.deepStrictEqual(BA.implies(undefined, undefined), undefined) diff --git a/test/Either.ts b/test/Either.ts index 215ddab23..a712818e8 100644 --- a/test/Either.ts +++ b/test/Either.ts @@ -1,12 +1,14 @@ -import * as U from './util' import { sequenceT } from '../src/Apply' import * as _ from '../src/Either' import { identity, pipe } from '../src/function' import * as N from '../src/number' import * as O from '../src/Option' +import * as RA from '../src/ReadonlyArray' +import { ReadonlyNonEmptyArray } from '../src/ReadonlyNonEmptyArray' +import { separated } from '../src/Separated' import * as S from '../src/string' import * as T from '../src/Task' -import { separated } from '../src/Separated' +import * as U from './util' describe('Either', () => { describe('pipeables', () => { @@ -114,6 +116,10 @@ describe('Either', () => { U.deepStrictEqual(pipe(_.right(_.right('a')), _.flatten), _.right('a')) }) + it('flattenW', () => { + U.deepStrictEqual(pipe(_.right<'left1', _.Either<'left2', 'a'>>(_.right('a')), _.flattenW), _.right('a')) + }) + it('bimap', () => { const f = (s: string): number => s.length const g = (n: number): boolean => n > 2 @@ -602,9 +608,23 @@ describe('Either', () => { U.deepStrictEqual(f(_.left('a')), _.left('a')) }) - it('sequenceArray', () => { - U.deepStrictEqual(pipe([_.right(1), _.right(2)], _.sequenceArray), _.right([1, 2])) - U.deepStrictEqual(pipe([_.right(1), _.left('a')], _.sequenceArray), _.left('a')) + describe('array utils', () => { + const input: ReadonlyNonEmptyArray = ['a', 'b'] + + it('traverseReadonlyArrayWithIndex', () => { + const f = _.traverseReadonlyArrayWithIndex((i, a: string) => (a.length > 0 ? _.right(a + i) : _.left('e'))) + U.deepStrictEqual(pipe(RA.empty, f), _.right(RA.empty)) + U.deepStrictEqual(pipe(input, f), _.right(['a0', 'b1'])) + U.deepStrictEqual(pipe(['a', ''], f), _.left('e')) + }) + + // old + it('sequenceArray', () => { + // tslint:disable-next-line: deprecation + U.deepStrictEqual(pipe([_.right(1), _.right(2)], _.sequenceArray), _.right([1, 2])) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(pipe([_.right(1), _.left('a')], _.sequenceArray), _.left('a')) + }) }) describe('getCompactable', () => { diff --git a/test/Endomorphism.ts b/test/Endomorphism.ts new file mode 100644 index 000000000..45538bd5c --- /dev/null +++ b/test/Endomorphism.ts @@ -0,0 +1,11 @@ +import * as _ from '../src/Endomorphism' +import * as U from './util' + +describe('Endomorphism', () => { + it('getMonoid', () => { + const M = _.getMonoid() + const inc = (n: number) => n + 1 + const f = M.concat(inc, U.double) + U.deepStrictEqual(f(3), 8) + }) +}) diff --git a/test/Eq.ts b/test/Eq.ts index 4fef10987..7c43c1426 100644 --- a/test/Eq.ts +++ b/test/Eq.ts @@ -77,4 +77,12 @@ describe('Eq', () => { U.deepStrictEqual(eq.equals(['a', 1, true], ['a', 2, true]), false) U.deepStrictEqual(eq.equals(['a', 1, true], ['a', 1, false]), false) }) + + it('eqDate', () => { + // tslint:disable-next-line: deprecation + const E = _.eqDate + U.deepStrictEqual(E.equals(new Date(0), new Date(0)), true) + U.deepStrictEqual(E.equals(new Date(0), new Date(1)), false) + U.deepStrictEqual(E.equals(new Date(1), new Date(0)), false) + }) }) diff --git a/test/Field.ts b/test/Field.ts index 10b4c6e60..c05fcfa39 100644 --- a/test/Field.ts +++ b/test/Field.ts @@ -1,18 +1,31 @@ import * as U from './util' -import { gcd, lcm } from '../src/Field' +import * as _ from '../src/Field' import * as N from '../src/number' describe('Field', () => { it('gcd', () => { - const gcdNumber = gcd(N.Eq, N.Field) + const gcdNumber = _.gcd(N.Eq, N.Field) U.deepStrictEqual(gcdNumber(10, 5), 5) U.deepStrictEqual(gcdNumber(10, 2), 2) U.deepStrictEqual(gcdNumber(10, 3), 1) }) it('lcm', () => { - const lcmNumber = lcm(N.Eq, N.Field) + const lcmNumber = _.lcm(N.Eq, N.Field) U.deepStrictEqual(lcmNumber(4, 6), 12) U.deepStrictEqual(lcmNumber(4, 0), 0) }) + + it('fieldNumber', () => { + // tslint:disable-next-line: deprecation + const F = _.fieldNumber + U.deepStrictEqual(F.add(1, 2), 3) + U.deepStrictEqual(F.div(4, 2), 2) + U.deepStrictEqual(F.mod(4, 2), 0) + U.deepStrictEqual(F.mul(4, 2), 8) + U.deepStrictEqual(F.sub(3, 2), 1) + U.deepStrictEqual(F.degree(0), 1) + U.deepStrictEqual(F.degree(1), 1) + U.deepStrictEqual(F.degree(2), 1) + }) }) diff --git a/test/IO.ts b/test/IO.ts index a40198b89..ad7007f45 100644 --- a/test/IO.ts +++ b/test/IO.ts @@ -1,8 +1,10 @@ -import * as U from './util' import * as E from '../src/Either' import { pipe } from '../src/function' import * as _ from '../src/IO' import * as N from '../src/number' +import * as RA from '../src/ReadonlyArray' +import { ReadonlyNonEmptyArray } from '../src/ReadonlyNonEmptyArray' +import * as U from './util' describe('IO', () => { describe('pipeables', () => { @@ -78,14 +80,26 @@ describe('IO', () => { U.deepStrictEqual(pipe(_.of(1), _.bindTo('a'), _.apS('b', _.of('b')))(), { a: 1, b: 'b' }) }) - it('sequenceArray', () => { - // tslint:disable-next-line: readonly-array - const log: Array = [] - const append = (n: number): _.IO => () => { - log.push(n) - return n - } - U.deepStrictEqual(pipe([append(1), append(2)], _.sequenceArray)(), [1, 2]) - U.deepStrictEqual(log, [1, 2]) + describe('array utils', () => { + const input: ReadonlyNonEmptyArray = ['a', 'b'] + + it('traverseReadonlyArrayWithIndex', () => { + const f = _.traverseReadonlyArrayWithIndex((i, a: string) => _.of(a + i)) + U.strictEqual(pipe(RA.empty, f)(), RA.empty) + U.deepStrictEqual(pipe(input, f)(), ['a0', 'b1']) + }) + + // old + it('sequenceArray', () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const append = (n: number): _.IO => () => { + log.push(n) + return n + } + // tslint:disable-next-line: deprecation + U.deepStrictEqual(pipe([append(1), append(2)], _.sequenceArray)(), [1, 2]) + U.deepStrictEqual(log, [1, 2]) + }) }) }) diff --git a/test/IOEither.ts b/test/IOEither.ts index 2ab221ad1..e7d313b47 100644 --- a/test/IOEither.ts +++ b/test/IOEither.ts @@ -1,7 +1,7 @@ import * as U from './util' import { sequenceT } from '../src/Apply' import * as E from '../src/Either' -import { identity, pipe } from '../src/function' +import { identity, pipe, SK } from '../src/function' import * as I from '../src/IO' import * as _ from '../src/IOEither' import * as O from '../src/Option' @@ -10,6 +10,7 @@ import * as RA from '../src/ReadonlyArray' import * as N from '../src/number' import * as S from '../src/string' import { left, right } from '../src/Separated' +import { ReadonlyNonEmptyArray } from '../src/ReadonlyNonEmptyArray' describe('IOEither', () => { describe('pipeables', () => { @@ -117,6 +118,10 @@ describe('IOEither', () => { U.deepStrictEqual(pipe(_.right(_.right('a')), _.flatten)(), E.right('a')) }) + it('flattenW', () => { + U.deepStrictEqual(pipe(_.right<'left1', _.IOEither<'left2', 'a'>>(_.right('a')), _.flattenW)(), E.right('a')) + }) + it('bimap', () => { const f = (s: string): number => s.length const g = (n: number): boolean => n > 2 @@ -251,6 +256,30 @@ describe('IOEither', () => { U.deepStrictEqual(_.orElse(() => _.right(2))(_.right(1))(), E.right(1)) }) + it('orElseW', () => { + U.deepStrictEqual(_.orElseW(() => _.right(2))(_.right(1))(), E.right(1)) + }) + + it('orElseFirst', () => { + const f = _.orElseFirst((e: string) => (e.length <= 1 ? _.right(true) : _.left(e + '!'))) + U.deepStrictEqual(pipe(_.right(1), f)(), E.right(1)) + U.deepStrictEqual(pipe(_.left('a'), f)(), E.left('a')) + U.deepStrictEqual(pipe(_.left('aa'), f)(), E.left('aa!')) + }) + + it('orElseFirstW', () => { + const f = _.orElseFirstW((e: string) => (e.length <= 1 ? _.right(true) : _.left(e + '!'))) + U.deepStrictEqual(pipe(_.right(1), f)(), E.right(1)) + U.deepStrictEqual(pipe(_.left('a'), f)(), E.left('a')) + U.deepStrictEqual(pipe(_.left('aa'), f)(), E.left('aa!')) + }) + + it('orLeft', () => { + const f = _.orLeft((e: string) => I.of(e + '!')) + U.deepStrictEqual(pipe(_.right(1), f)(), E.right(1)) + U.deepStrictEqual(pipe(_.left('a'), f)(), E.left('a!')) + }) + it('tryCatch', () => { U.deepStrictEqual(_.tryCatch(() => 1, E.toError)(), E.right(1)) U.deepStrictEqual( @@ -458,42 +487,100 @@ describe('IOEither', () => { ) }) - it('sequenceArray', () => { - // tslint:disable-next-line: readonly-array - const log: Array = [] - const right = (n: number): _.IOEither => - _.rightIO(() => { - log.push(n) - return n - }) - const left = (s: string): _.IOEither => - _.leftIO(() => { - log.push(s) - return s - }) - U.deepStrictEqual(pipe([right(1), right(2)], _.sequenceArray)(), E.right([1, 2])) - U.deepStrictEqual(pipe([right(3), left('a')], _.sequenceArray)(), E.left('a')) - U.deepStrictEqual(pipe([left('b'), right(4)], _.sequenceArray)(), E.left('b')) - U.deepStrictEqual(log, [1, 2, 3, 'a', 'b', 4]) - }) + describe('array utils', () => { + const input: ReadonlyNonEmptyArray = ['a', 'b'] - it('sequenceSeqArray', () => { - // tslint:disable-next-line: readonly-array - const log: Array = [] - const right = (n: number): _.IOEither => - _.rightIO(() => { - log.push(n) - return n - }) - const left = (s: string): _.IOEither => - _.leftIO(() => { - log.push(s) - return s - }) - U.deepStrictEqual(pipe([right(1), right(2)], _.sequenceSeqArray)(), E.right([1, 2])) - U.deepStrictEqual(pipe([right(3), left('a')], _.sequenceSeqArray)(), E.left('a')) - U.deepStrictEqual(pipe([left('b'), right(4)], _.sequenceSeqArray)(), E.left('b')) - U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + it('traverseReadonlyArrayWithIndex', () => { + const f = _.traverseReadonlyArrayWithIndex((i, a: string) => (a.length > 0 ? _.right(a + i) : _.left('e'))) + U.deepStrictEqual(pipe(RA.empty, f)(), E.right(RA.empty)) + U.deepStrictEqual(pipe(input, f)(), E.right(['a0', 'b1'])) + U.deepStrictEqual(pipe(['a', ''], f)(), E.left('e')) + }) + + it('sequenceReadonlyArray', () => { + U.deepStrictEqual(pipe(RA.empty, _.traverseReadonlyArrayWithIndex(SK))(), E.right(RA.empty)) + + const log: Array = [] + const right = (n: number): _.IOEither => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.IOEither => + _.leftIO(() => { + log.push(s) + return s + }) + U.deepStrictEqual(pipe([right(1), right(2)], _.traverseReadonlyArrayWithIndex(SK))(), E.right([1, 2])) + U.deepStrictEqual(pipe([right(3), left('a')], _.traverseReadonlyArrayWithIndex(SK))(), E.left('a')) + U.deepStrictEqual(pipe([left('b'), right(4)], _.traverseReadonlyArrayWithIndex(SK))(), E.left('b')) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b', 4]) + }) + + it('sequenceReadonlyArraySeq', () => { + U.deepStrictEqual(pipe(RA.empty, _.traverseReadonlyArrayWithIndexSeq(SK))(), E.right(RA.empty)) + + const log: Array = [] + const right = (n: number): _.IOEither => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.IOEither => + _.leftIO(() => { + log.push(s) + return s + }) + U.deepStrictEqual(pipe([right(1), right(2)], _.traverseReadonlyArrayWithIndexSeq(SK))(), E.right([1, 2])) + U.deepStrictEqual(pipe([right(3), left('a')], _.traverseReadonlyArrayWithIndexSeq(SK))(), E.left('a')) + U.deepStrictEqual(pipe([left('b'), right(4)], _.traverseReadonlyArrayWithIndexSeq(SK))(), E.left('b')) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + }) + + // old + it('sequenceArray', () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const right = (n: number): _.IOEither => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.IOEither => + _.leftIO(() => { + log.push(s) + return s + }) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(pipe([right(1), right(2)], _.sequenceArray)(), E.right([1, 2])) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(pipe([right(3), left('a')], _.sequenceArray)(), E.left('a')) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(pipe([left('b'), right(4)], _.sequenceArray)(), E.left('b')) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b', 4]) + }) + + it('sequenceSeqArray', () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const right = (n: number): _.IOEither => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.IOEither => + _.leftIO(() => { + log.push(s) + return s + }) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(pipe([right(1), right(2)], _.sequenceSeqArray)(), E.right([1, 2])) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(pipe([right(3), left('a')], _.sequenceSeqArray)(), E.left('a')) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(pipe([left('b'), right(4)], _.sequenceSeqArray)(), E.left('b')) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + }) }) it('tryCatchK', () => { diff --git a/test/Magma.ts b/test/Magma.ts new file mode 100644 index 000000000..9a0f9a673 --- /dev/null +++ b/test/Magma.ts @@ -0,0 +1,42 @@ +import { increment, pipe } from '../src/function' +import * as _ from '../src/Magma' +import * as N from '../src/number' +import * as U from './util' + +describe('Magma', () => { + it('reverse', () => { + const subAll = _.concatAll(_.reverse(N.MagmaSub))(0) + U.deepStrictEqual(subAll([1, 2, 3]), 2) + }) + + it('filterFirst', () => { + const M = pipe( + N.SemigroupSum, + _.filterFirst((n) => n >= 0) + ) + // sum ignoring negative partials + const sum = _.concatAll(M)(0) + U.deepStrictEqual(sum([1, -2, 3]), 3) + }) + + it('filterSecond', () => { + const M = pipe( + N.SemigroupSum, + _.filterSecond((n) => n >= 0) + ) + // sum ignoring negative elements + const sum = _.concatAll(M)(0) + U.deepStrictEqual(sum([1, -2, 3]), 4) + }) + + it('endo', () => { + const M = pipe(N.SemigroupSum, _.endo(increment)) + const sum = _.concatAll(M)(0) + U.deepStrictEqual(sum([1, -2, 3]), 8) + }) + + it('concatAll', () => { + const subAll = _.concatAll(N.MagmaSub)(0) + U.deepStrictEqual(subAll([1, 2, 3]), -6) + }) +}) diff --git a/test/Map.ts b/test/Map.ts index df2d0bc7c..fee42208d 100644 --- a/test/Map.ts +++ b/test/Map.ts @@ -1,18 +1,19 @@ -import * as U from './util' +import * as assert from 'assert' import { Either, left, right } from '../src/Either' import { Eq, fromEquals } from '../src/Eq' -import { identity, pipe, Refinement } from '../src/function' +import { identity, pipe } from '../src/function' import * as _ from '../src/Map' import * as N from '../src/number' import * as O from '../src/Option' import * as Ord from '../src/Ord' import * as RA from '../src/ReadonlyArray' +import { Refinement } from '../src/Refinement' import * as Se from '../src/Semigroup' -import { struct, Show } from '../src/Show' +import { separated } from '../src/Separated' +import { Show, struct } from '../src/Show' import * as S from '../src/string' import * as T from '../src/Task' -import * as assert from 'assert' -import { separated } from '../src/Separated' +import * as U from './util' interface User { readonly id: string @@ -740,25 +741,14 @@ describe('Map', () => { }) }) - describe('getWitherable', () => { - const W = _.getWitherable(ordUser) - - it('mapWithIndex', () => { - const mapWithIndex = W.mapWithIndex - const aa1 = new Map([[{ id: 'aa' }, 1]]) - const aa3 = new Map([[{ id: 'aa' }, 3]]) - U.deepStrictEqual( - mapWithIndex(aa1, (k, a) => a + k.id.length), - aa3 - ) - }) - + describe('getFoldable', () => { + const F = _.getFoldable(ordUser) it('reduce', () => { const d1 = new Map([ [{ id: 'k1' }, 'a'], [{ id: 'k2' }, 'b'] ]) - const reduceO = W.reduce + const reduceO = F.reduce U.deepStrictEqual( reduceO(d1, '', (b, a) => b + a), 'ab' @@ -774,7 +764,7 @@ describe('Map', () => { }) it('foldMap', () => { - const foldMapOM = W.foldMap(S.Monoid) + const foldMapOM = F.foldMap(S.Monoid) const m = new Map([ [{ id: 'a' }, 'a'], [{ id: 'a' }, 'b'] @@ -783,7 +773,7 @@ describe('Map', () => { }) it('reduceRight', () => { - const reduceRightO = W.reduceRight + const reduceRightO = F.reduceRight const m = new Map([ [{ id: 'a' }, 'a'], [{ id: 'b' }, 'b'] @@ -792,6 +782,20 @@ describe('Map', () => { const f = (a: string, acc: string) => acc + a U.deepStrictEqual(reduceRightO(m, init, f), 'ba') }) + }) + + describe('getWitherable', () => { + const W = _.getWitherable(ordUser) + + it('mapWithIndex', () => { + const mapWithIndex = W.mapWithIndex + const aa1 = new Map([[{ id: 'aa' }, 1]]) + const aa3 = new Map([[{ id: 'aa' }, 3]]) + U.deepStrictEqual( + mapWithIndex(aa1, (k, a) => a + k.id.length), + aa3 + ) + }) it('reduceWithIndex', () => { const d1 = new Map([ @@ -1088,4 +1092,77 @@ describe('Map', () => { aa3 ) }) + + it('getUnionMonoid', () => { + const M = _.getUnionMonoid(eqUser, S.Semigroup) + const x = new Map([ + [{ id: 'a' }, 'a1'], + [{ id: 'b' }, 'b1'], + [{ id: 'c' }, 'c1'] + ]) + const y = new Map([ + [{ id: 'b' }, 'b2'], + [{ id: 'c' }, 'c2'], + [{ id: 'd' }, 'd2'] + ]) + U.deepStrictEqual(M.concat(x, M.empty), x) + U.deepStrictEqual(M.concat(M.empty, x), x) + U.deepStrictEqual(M.concat(x, new Map()), x) + U.deepStrictEqual(M.concat(new Map(), x), x) + U.deepStrictEqual( + M.concat(x, y), + new Map([ + [{ id: 'a' }, 'a1'], + [{ id: 'b' }, 'b1b2'], + [{ id: 'c' }, 'c1c2'], + [{ id: 'd' }, 'd2'] + ]) + ) + }) + + it('getIntersectionSemigroup', () => { + const M = _.getIntersectionSemigroup(eqUser, S.Semigroup) + const x = new Map([ + [{ id: 'a' }, 'a1'], + [{ id: 'b' }, 'b1'], + [{ id: 'c' }, 'c1'] + ]) + const y = new Map([ + [{ id: 'b' }, 'b2'], + [{ id: 'c' }, 'c2'], + [{ id: 'd' }, 'd2'] + ]) + U.deepStrictEqual(M.concat(x, new Map()), new Map()) + U.deepStrictEqual(M.concat(new Map(), x), new Map()) + U.deepStrictEqual( + M.concat(x, y), + new Map([ + [{ id: 'b' }, 'b1b2'], + [{ id: 'c' }, 'c1c2'] + ]) + ) + }) + + it('getDifferenceMagma', () => { + const M = _.getDifferenceMagma(eqUser)() + const x = new Map([ + [{ id: 'a' }, 'a1'], + [{ id: 'b' }, 'b1'], + [{ id: 'c' }, 'c1'] + ]) + const y = new Map([ + [{ id: 'b' }, 'b2'], + [{ id: 'c' }, 'c2'], + [{ id: 'd' }, 'd2'] + ]) + U.deepStrictEqual(M.concat(x, new Map()), x) + U.deepStrictEqual(M.concat(new Map(), x), x) + U.deepStrictEqual( + M.concat(x, y), + new Map([ + [{ id: 'a' }, 'a1'], + [{ id: 'd' }, 'd2'] + ]) + ) + }) }) diff --git a/test/NonEmptyArray.ts b/test/NonEmptyArray.ts index a9f589517..fc165c9ca 100644 --- a/test/NonEmptyArray.ts +++ b/test/NonEmptyArray.ts @@ -1,4 +1,5 @@ import * as assert from 'assert' +import { Endomorphism } from '../src/Endomorphism' import { identity, pipe } from '../src/function' import * as _ from '../src/NonEmptyArray' import * as N from '../src/number' @@ -151,7 +152,9 @@ describe('NonEmptyArray', () => { }) it('groupSort', () => { + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.groupSort(N.Ord)([]), []) + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.groupSort(N.Ord)([1, 2, 1, 1]), [[1, 1, 1], [2]]) }) @@ -197,6 +200,13 @@ describe('NonEmptyArray', () => { }) }) + it('union', () => { + const concat = _.getUnionSemigroup(N.Eq).concat + U.deepStrictEqual(concat([1, 2], [3, 4]), [1, 2, 3, 4]) + U.deepStrictEqual(concat([1, 2], [2, 3]), [1, 2, 3]) + U.deepStrictEqual(concat([1, 2], [1, 2]), [1, 2]) + }) + it('insertAt', () => { const make = (x: number) => ({ x }) const a1 = make(1) @@ -265,16 +275,17 @@ describe('NonEmptyArray', () => { const a1 = make(1) const a2 = make(1) const a3 = make(2) + const as: _.NonEmptyArray<{ readonly x: number }> = [a1, a2, a3] U.deepStrictEqual( pipe( - [a1, a2, a3], + as, _.filter(({ x }) => x !== 1) ), O.some([a3]) ) U.deepStrictEqual( pipe( - [a1, a2, a3], + as, _.filter(({ x }) => x !== 2) ), O.some([a1, a2]) @@ -287,7 +298,7 @@ describe('NonEmptyArray', () => { ) U.deepStrictEqual( pipe( - [a1, a2, a3], + as, _.filter(({ x }) => x !== 10) ), O.some([a1, a2, a3]) @@ -371,8 +382,7 @@ describe('NonEmptyArray', () => { U.deepStrictEqual(Sh.show(['a', 'b', 'c']), `["a", "b", "c"]`) }) - it('alt / concat', () => { - U.deepStrictEqual(_.concat(['a'], []), ['a']) + it('alt', () => { U.deepStrictEqual( pipe( ['a'], @@ -483,4 +493,73 @@ describe('NonEmptyArray', () => { // n out of bounds assertSingleChunk([1, 2], 3) }) + + it('matchLeft', () => { + U.deepStrictEqual( + pipe( + [1, 2, 3], + _.matchLeft((head, tail) => [head, tail]) + ), + [1, [2, 3]] + ) + }) + + it('matchRight', () => { + U.deepStrictEqual( + pipe( + [1, 2, 3], + _.matchRight((init, last) => [init, last]) + ), + [[1, 2], 3] + ) + }) + + it('modifyHead', () => { + const f: Endomorphism = (s) => s + '!' + U.deepStrictEqual(pipe(['a'], _.modifyHead(f)), ['a!']) + U.deepStrictEqual(pipe(['a', 'b'], _.modifyHead(f)), ['a!', 'b']) + U.deepStrictEqual(pipe(['a', 'b', 'c'], _.modifyHead(f)), ['a!', 'b', 'c']) + }) + + it('modifyLast', () => { + const f: Endomorphism = (s) => s + '!' + U.deepStrictEqual(pipe(['a'], _.modifyLast(f)), ['a!']) + U.deepStrictEqual(pipe(['a', 'b'], _.modifyLast(f)), ['a', 'b!']) + U.deepStrictEqual(pipe(['a', 'b', 'c'], _.modifyLast(f)), ['a', 'b', 'c!']) + }) + + it('replicate', () => { + const f = _.replicate('a') + U.deepStrictEqual(pipe(0, f), ['a']) + U.deepStrictEqual(pipe(1, f), ['a']) + U.deepStrictEqual(pipe(2, f), ['a', 'a']) + }) + + it('updateHead', () => { + U.deepStrictEqual(pipe(['a'], _.updateHead('d')), ['d']) + U.deepStrictEqual(pipe(['a', 'b'], _.updateHead('d')), ['d', 'b']) + U.deepStrictEqual(pipe(['a', 'b', 'c'], _.updateHead('d')), ['d', 'b', 'c']) + }) + + it('updateLast', () => { + U.deepStrictEqual(pipe(['a'], _.updateLast('d')), ['d']) + U.deepStrictEqual(pipe(['a', 'b'], _.updateLast('d')), ['a', 'd']) + U.deepStrictEqual(pipe(['a', 'b', 'c'], _.updateLast('d')), ['a', 'b', 'd']) + }) + + it('concatW', () => { + U.deepStrictEqual(pipe(['a'], _.concatW(['b'])), ['a', 'b']) + }) + + it('concat', () => { + U.deepStrictEqual(pipe(['a'], _.concat(['b'])), ['a', 'b']) + U.deepStrictEqual(pipe([], _.concat(['b'])), ['b']) + U.deepStrictEqual(pipe(['a'], _.concat([])), ['a']) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(_.concat(['a'], ['b']), ['a', 'b']) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(_.concat(['a'], []), ['a']) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(_.concat([], ['b']), ['b']) + }) }) diff --git a/test/Option.ts b/test/Option.ts index 527d72480..d148a2a72 100644 --- a/test/Option.ts +++ b/test/Option.ts @@ -7,6 +7,7 @@ import * as RA from '../src/ReadonlyArray' import * as S from '../src/string' import * as T from '../src/Task' import { separated } from '../src/Separated' +import { ReadonlyNonEmptyArray } from '../src/ReadonlyNonEmptyArray' const p = (n: number): boolean => n > 2 @@ -370,18 +371,20 @@ describe('Option', () => { }) it('getFirstMonoid', () => { + // tslint:disable-next-line: deprecation const M = _.getFirstMonoid() U.deepStrictEqual(M.concat(_.none, _.none), _.none) U.deepStrictEqual(M.concat(_.some(1), _.none), _.some(1)) - U.deepStrictEqual(M.concat(_.none, _.some(1)), _.some(1)) + U.deepStrictEqual(M.concat(_.none, _.some(2)), _.some(2)) U.deepStrictEqual(M.concat(_.some(1), _.some(2)), _.some(1)) }) it('getLastMonoid', () => { + // tslint:disable-next-line: deprecation const M = _.getLastMonoid() U.deepStrictEqual(M.concat(_.none, _.none), _.none) U.deepStrictEqual(M.concat(_.some(1), _.none), _.some(1)) - U.deepStrictEqual(M.concat(_.none, _.some(1)), _.some(1)) + U.deepStrictEqual(M.concat(_.none, _.some(2)), _.some(2)) U.deepStrictEqual(M.concat(_.some(1), _.some(2)), _.some(2)) }) @@ -421,12 +424,14 @@ describe('Option', () => { it('getRefinement', () => { const f = (s: string | number): _.Option => (typeof s === 'string' ? _.some(s) : _.none) + // tslint:disable-next-line: deprecation const isString = _.getRefinement(f) U.deepStrictEqual(isString('s'), true) U.deepStrictEqual(isString(1), false) type A = { readonly type: 'A' } type B = { readonly type: 'B' } type C = A | B + // tslint:disable-next-line: deprecation const isA = _.getRefinement((c) => (c.type === 'A' ? _.some(c) : _.none)) U.deepStrictEqual(isA({ type: 'A' }), true) U.deepStrictEqual(isA({ type: 'B' }), false) @@ -473,9 +478,23 @@ describe('Option', () => { U.deepStrictEqual(f(-1), _.none) }) - it('sequenceArray', () => { - U.deepStrictEqual(pipe([_.of(1), _.of(2)], _.sequenceArray), _.some([1, 2])) - U.deepStrictEqual(pipe([_.of(1), _.none], _.sequenceArray), _.none) + describe('array utils', () => { + const input: ReadonlyNonEmptyArray = ['a', 'b'] + + it('traverseReadonlyArrayWithIndex', () => { + const f = _.traverseReadonlyArrayWithIndex((i, a: string) => (a.length > 0 ? _.some(a + i) : _.none)) + U.deepStrictEqual(pipe(RA.empty, f), _.some(RA.empty)) + U.deepStrictEqual(pipe(input, f), _.some(['a0', 'b1'])) + U.deepStrictEqual(pipe(['a', ''], f), _.none) + }) + + // old + it('sequenceArray', () => { + // tslint:disable-next-line: deprecation + U.deepStrictEqual(pipe([_.of(1), _.of(2)], _.sequenceArray), _.some([1, 2])) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(pipe([_.of(1), _.none], _.sequenceArray), _.none) + }) }) it('tryCatchK', () => { @@ -489,4 +508,25 @@ describe('Option', () => { U.deepStrictEqual(f('a'), _.some(1)) U.deepStrictEqual(f(''), _.none) }) + + it('guard', () => { + U.deepStrictEqual( + pipe( + _.Do, + _.bind('x', () => _.some('a')), + _.bind('y', () => _.some('a')), + _.chainFirst(({ x, y }) => _.guard(x === y)) + ), + _.some({ x: 'a', y: 'a' }) + ) + U.deepStrictEqual( + pipe( + _.Do, + _.bind('x', () => _.some('a')), + _.bind('y', () => _.some('b')), + _.chainFirst(({ x, y }) => _.guard(x === y)) + ), + _.none + ) + }) }) diff --git a/test/Ord.ts b/test/Ord.ts index 4baef5e8d..5b2460281 100644 --- a/test/Ord.ts +++ b/test/Ord.ts @@ -4,6 +4,7 @@ import { concatAll } from '../src/Monoid' import * as N from '../src/number' import * as _ from '../src/Ord' import { sort } from '../src/ReadonlyArray' +import * as RR from '../src/ReadonlyRecord' import * as S from '../src/string' import * as U from './util' @@ -140,4 +141,30 @@ describe('Ord', () => { const second = { a: 1 } U.strictEqual(max(first, second), first) }) + + it('equals', () => { + const equals = _.equals(N.Ord) + U.deepStrictEqual(equals(1)(1), true) + U.deepStrictEqual(equals(1)(2), false) + }) + + it('trivial', () => { + const toReadonlyArray = RR.collect(_.trivial)((k, a) => [k, a]) + U.deepStrictEqual(toReadonlyArray({ a: 1, b: 2 }), [ + ['a', 1], + ['b', 2] + ]) + U.deepStrictEqual(toReadonlyArray({ b: 2, a: 1 }), [ + ['b', 2], + ['a', 1] + ]) + }) + + it('ordDate', () => { + // tslint:disable-next-line: deprecation + const O = _.ordDate + U.deepStrictEqual(O.compare(new Date(0), new Date(0)), 0) + U.deepStrictEqual(O.compare(new Date(0), new Date(1)), -1) + U.deepStrictEqual(O.compare(new Date(1), new Date(0)), 1) + }) }) diff --git a/test/Predicate.ts b/test/Predicate.ts new file mode 100644 index 000000000..e23e1cb08 --- /dev/null +++ b/test/Predicate.ts @@ -0,0 +1,55 @@ +import { pipe } from '../src/function' +import * as _ from '../src/Predicate' +import * as U from './util' + +const isPositive: _.Predicate = (n) => n > 0 +const isNegative: _.Predicate = (n) => n < 0 +const lt2: _.Predicate = (n) => n < 2 + +describe('Predicate', () => { + it('contramap', () => { + type A = { + readonly a: number + } + const predicate = pipe( + isPositive, + _.contramap((a: A) => a.a) + ) + U.deepStrictEqual(predicate({ a: -1 }), false) + U.deepStrictEqual(predicate({ a: 0 }), false) + U.deepStrictEqual(predicate({ a: 1 }), true) + }) + + it('Contravariant.contramap', () => { + type A = { + readonly a: number + } + const predicate = _.Contravariant.contramap(isPositive, (a: A) => a.a) + U.deepStrictEqual(predicate({ a: -1 }), false) + U.deepStrictEqual(predicate({ a: 0 }), false) + U.deepStrictEqual(predicate({ a: 1 }), true) + }) + + it('not', () => { + const predicate = _.not(isPositive) + U.deepStrictEqual(predicate(1), false) + U.deepStrictEqual(predicate(0), true) + U.deepStrictEqual(predicate(-1), true) + }) + + it('getMonoidAny', () => { + const M = _.getMonoidAny() + const predicate = M.concat(isPositive, isNegative) + U.deepStrictEqual(predicate(0), false) + U.deepStrictEqual(predicate(-1), true) + U.deepStrictEqual(predicate(1), true) + }) + + it('getMonoidAll', () => { + const M = _.getMonoidAll() + const predicate = M.concat(isPositive, lt2) + U.deepStrictEqual(predicate(0), false) + U.deepStrictEqual(predicate(-2), false) + U.deepStrictEqual(predicate(1), true) + }) +}) diff --git a/test/Reader.ts b/test/Reader.ts index 26f41c8b5..188cc7052 100644 --- a/test/Reader.ts +++ b/test/Reader.ts @@ -1,8 +1,10 @@ -import * as U from './util' import { pipe } from '../src/function' import * as N from '../src/number' -import * as S from '../src/string' import * as _ from '../src/Reader' +import * as RA from '../src/ReadonlyArray' +import { ReadonlyNonEmptyArray } from '../src/ReadonlyNonEmptyArray' +import * as S from '../src/string' +import * as U from './util' interface Env { readonly count: number @@ -36,10 +38,22 @@ describe('Reader', () => { U.deepStrictEqual(pipe(_.of('foo'), _.chainFirst(f))({}), 'foo') }) - it('chain', () => { + it('chainFirstW', () => { + const f = (s: string) => _.of(s.length) + U.deepStrictEqual(pipe(_.of('foo'), _.chainFirstW(f))({}), 'foo') + }) + + it('flatten', () => { U.deepStrictEqual(pipe(_.of(_.of('a')), _.flatten)({}), 'a') }) + type R1 = { readonly env1: unknown } + type R2 = { readonly env2: unknown } + + it('flattenW', () => { + U.deepStrictEqual(pipe(_.of>(_.of('a')), _.flattenW)({ env1: '', env2: '' }), 'a') + }) + it('compose', () => { U.deepStrictEqual(pipe(U.double, _.compose(S.size))('aaa'), 6) }) @@ -125,7 +139,25 @@ describe('Reader', () => { U.deepStrictEqual(pipe(_.of(1), _.bindTo('a'), _.apS('b', _.of('b')))(undefined), { a: 1, b: 'b' }) }) - it('sequenceArray', () => { - U.deepStrictEqual(pipe([_.of(1), _.of(2)], _.sequenceArray)(undefined), [1, 2]) + describe('array utils', () => { + const input: ReadonlyNonEmptyArray = ['a', 'b'] + + it('traverseReadonlyArrayWithIndex', () => { + const f = _.traverseReadonlyArrayWithIndex((i, a: string) => _.of(a + i)) + U.strictEqual(pipe(RA.empty, f)({}), RA.empty) + U.deepStrictEqual(pipe(input, f)({}), ['a0', 'b1']) + }) + + // old + it('sequenceArray', () => { + // tslint:disable-next-line: deprecation + U.deepStrictEqual(pipe([_.of(1), _.of(2)], _.sequenceArray)(undefined), [1, 2]) + }) + }) + + it('asksReader', () => { + const e: Env = { count: 0 } + const f = (e: Env) => _.of(e.count + 1) + U.deepStrictEqual(_.asksReader(f)(e), 1) }) }) diff --git a/test/ReaderEither.ts b/test/ReaderEither.ts index 0cd1b8faf..51002c437 100644 --- a/test/ReaderEither.ts +++ b/test/ReaderEither.ts @@ -1,13 +1,15 @@ -import * as U from './util' import * as Apply from '../src/Apply' import * as E from '../src/Either' import { pipe } from '../src/function' +import * as N from '../src/number' import * as O from '../src/Option' import * as R from '../src/Reader' import * as _ from '../src/ReaderEither' -import * as S from '../src/string' -import * as N from '../src/number' +import * as RA from '../src/ReadonlyArray' +import { ReadonlyNonEmptyArray } from '../src/ReadonlyNonEmptyArray' import { left, right } from '../src/Separated' +import * as S from '../src/string' +import * as U from './util' describe('ReaderEither', () => { describe('pipeables', () => { @@ -58,6 +60,18 @@ describe('ReaderEither', () => { U.deepStrictEqual(pipe(_.right(_.right('a')), _.flatten)({}), E.right('a')) }) + type R1 = { readonly env1: unknown } + type R2 = { readonly env2: unknown } + type E1 = { readonly left1: unknown } + type E2 = { readonly left2: unknown } + + it('flattenW', () => { + U.deepStrictEqual( + pipe(_.right>(_.right('a')), _.flattenW)({ env1: '', env2: '' }), + E.right('a') + ) + }) + it('mapLeft', () => { U.deepStrictEqual(pipe(_.right(1), _.mapLeft(S.size))({}), E.right(1)) U.deepStrictEqual(pipe(_.left('aa'), _.mapLeft(S.size))({}), E.left(2)) @@ -134,6 +148,31 @@ describe('ReaderEither', () => { U.deepStrictEqual(orElse(_.right(1))({}), E.right(1)) }) + it('orElseW', () => { + const orElse = _.orElseW((s: string) => (s.length > 2 ? _.right(1) : _.left(2))) + U.deepStrictEqual(orElse(_.right(1))({}), E.right(1)) + }) + + it('orElseFirst', () => { + const f = _.orElseFirst((s: string) => (s.length <= 1 ? _.right(true) : _.left(s + '!'))) + U.deepStrictEqual(pipe(_.right(1), f)({}), E.right(1)) + U.deepStrictEqual(pipe(_.left('a'), f)({}), E.left('a')) + U.deepStrictEqual(pipe(_.left('aa'), f)({}), E.left('aa!')) + }) + + it('orElseFirstW', () => { + const f = _.orElseFirstW((s: string) => (s.length <= 1 ? _.right(true) : _.left(s + '!'))) + U.deepStrictEqual(pipe(_.right(1), f)({}), E.right(1)) + U.deepStrictEqual(pipe(_.left('a'), f)({}), E.left('a')) + U.deepStrictEqual(pipe(_.left('aa'), f)({}), E.left('aa!')) + }) + + it('orLeft', () => { + const f = _.orLeft((s: string) => R.of(s + '!')) + U.deepStrictEqual(pipe(_.right(1), f)({}), E.right(1)) + U.deepStrictEqual(pipe(_.left('a'), f)({}), E.left('a!')) + }) + describe('getSemigroup', () => { it('concat', () => { // tslint:disable-next-line: deprecation @@ -186,11 +225,7 @@ describe('ReaderEither', () => { }) it('local', () => { - U.deepStrictEqual( - // tslint:disable-next-line: deprecation - _.local((n: number) => ({ a: n }))((r: { readonly a: number }) => E.right(r.a))(1), - E.right(1) - ) + U.deepStrictEqual(_.local((n: number) => ({ a: n }))((r: { readonly a: number }) => E.right(r.a))(1), E.right(1)) }) it('getApplicativeReaderValidation', () => { @@ -233,9 +268,23 @@ describe('ReaderEither', () => { ) }) - it('sequenceArray', () => { - U.deepStrictEqual(pipe([_.right(1), _.right(2)], _.sequenceArray)(undefined), E.right([1, 2])) - U.deepStrictEqual(pipe([_.right(1), _.left('a')], _.sequenceArray)(undefined), E.left('a')) + describe('array utils', () => { + const input: ReadonlyNonEmptyArray = ['a', 'b'] + + it('traverseReadonlyArrayWithIndex', () => { + const f = _.traverseReadonlyArrayWithIndex((i, a: string) => (a.length > 0 ? _.right(a + i) : _.left('e'))) + U.deepStrictEqual(pipe(RA.empty, f)({}), E.right(RA.empty)) + U.deepStrictEqual(pipe(input, f)({}), E.right(['a0', 'b1'])) + U.deepStrictEqual(pipe(['a', ''], f)({}), E.left('e')) + }) + + // old + it('sequenceArray', () => { + // tslint:disable-next-line: deprecation + U.deepStrictEqual(pipe([_.right(1), _.right(2)], _.sequenceArray)(undefined), E.right([1, 2])) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(pipe([_.right(1), _.left('a')], _.sequenceArray)(undefined), E.left('a')) + }) }) it('getCompactable', () => { @@ -272,4 +321,31 @@ describe('ReaderEither', () => { U.deepStrictEqual(f(_.right(1))({}), 'right') U.deepStrictEqual(f(_.left('a'))({}), 'left') }) + + it('fromReaderK', () => { + const ma = _.fromReaderK((n: number): R.Reader => (c) => n * c) + U.deepStrictEqual(ma(3)(2), E.right(6)) + }) + + it('chainReaderK', () => { + const f = _.chainReaderK((n: number): R.Reader => (c) => n * c) + U.deepStrictEqual(pipe(_.right(3), f)(2), E.right(6)) + U.deepStrictEqual(pipe(_.left('a'), f)(2), E.left('a')) + }) + + it('chainReaderKW', () => { + const f = _.chainReaderKW((): R.Reader => () => 2) + U.deepStrictEqual(pipe(_.right<{}, never, number>(3), f)({}), E.right(2)) + }) + + it('chainFirstReaderK', () => { + const f = _.chainFirstReaderK((n: number): R.Reader => (c) => n * c) + U.deepStrictEqual(pipe(_.right(3), f)(2), E.right(3)) + U.deepStrictEqual(pipe(_.left('a'), f)(2), E.left('a')) + }) + + it('chainFirstReaderKW', () => { + const f = _.chainFirstReaderKW((): R.Reader => () => 2) + U.deepStrictEqual(pipe(_.right<{}, never, number>(3), f)({}), E.right(3)) + }) }) diff --git a/test/ReaderT.ts b/test/ReaderT.ts new file mode 100644 index 000000000..ae40d96ee --- /dev/null +++ b/test/ReaderT.ts @@ -0,0 +1,14 @@ +import * as E from '../src/Either' +import * as IO from '../src/IO' +import * as _ from '../src/ReaderT' +import * as TE from '../src/TaskEither' +import * as U from './util' + +describe('ReaderT', () => { + it('fromNaturalTransformation', async () => { + const fromReaderIO = _.fromNaturalTransformation(TE.fromIO) + const f = (s: string): IO.IO => IO.of(s.length) + const fa = fromReaderIO(f) + U.deepStrictEqual(await fa('a')(), E.right(1)) + }) +}) diff --git a/test/ReaderTask.ts b/test/ReaderTask.ts index fab9343b8..54bc3849a 100644 --- a/test/ReaderTask.ts +++ b/test/ReaderTask.ts @@ -1,9 +1,10 @@ -import { pipe } from '../src/function' +import { pipe, SK } from '../src/function' import * as I from '../src/IO' import { monoidString } from '../src/Monoid' import * as R from '../src/Reader' import * as _ from '../src/ReaderTask' import * as RA from '../src/ReadonlyArray' +import { ReadonlyNonEmptyArray } from '../src/ReadonlyNonEmptyArray' import { semigroupString } from '../src/Semigroup' import * as S from '../src/string' import * as T from '../src/Task' @@ -41,10 +42,22 @@ describe('ReaderTask', () => { U.deepStrictEqual(await pipe(_.of('foo'), _.chainFirst(f))({})(), 'foo') }) + it('chainFirstW', async () => { + const f = (a: string) => _.of(a.length) + U.deepStrictEqual(await pipe(_.of('foo'), _.chainFirstW(f))({})(), 'foo') + }) + it('flatten', async () => { U.deepStrictEqual(await pipe(_.of(_.of('a')), _.flatten)({})(), 'a') }) + type R1 = { readonly env1: unknown } + type R2 = { readonly env2: unknown } + + it('flattenW', async () => { + U.deepStrictEqual(await pipe(_.of>(_.of('a')), _.flattenW)({ env1: '', env2: '' })(), 'a') + }) + it('of', async () => { U.deepStrictEqual(await _.fromReader(R.of(1))({})(), 1) }) @@ -81,7 +94,6 @@ describe('ReaderTask', () => { U.deepStrictEqual( await pipe( _.asks((n: number) => n + 1), - // tslint:disable-next-line: deprecation _.local(S.size) )('aaa')(), 4 @@ -158,37 +170,84 @@ describe('ReaderTask', () => { U.deepStrictEqual(await pipe(_.of(1), _.bindTo('a'), _.apS('b', _.of('b')))(undefined)(), { a: 1, b: 'b' }) }) - it('sequenceArray', async () => { - // tslint:disable-next-line: readonly-array - const log: Array = [] - const append = (n: number): _.ReaderTask => - _.fromTask( - T.delay(n % 2 === 0 ? 50 : 100)( - T.fromIO(() => { - log.push(n) - return n - }) + describe('array utils', () => { + const input: ReadonlyNonEmptyArray = ['a', 'b'] + + it('traverseReadonlyArrayWithIndex', async () => { + const f = _.traverseReadonlyArrayWithIndex((i, a: string) => _.of(a + i)) + U.deepStrictEqual(await pipe(RA.empty, f)(undefined)(), RA.empty) + U.deepStrictEqual(await pipe(input, f)(undefined)(), ['a0', 'b1']) + }) + + it('sequenceReadonlyArray', async () => { + U.deepStrictEqual(await pipe(RA.empty, _.traverseReadonlyArrayWithIndex(SK))(undefined)(), RA.empty) + const log: Array = [] + const append = (n: number): _.ReaderTask => + _.fromTask( + T.delay(n % 2 === 0 ? 50 : 100)( + T.fromIO(() => { + log.push(n) + return n + }) + ) + ) + const as = RA.makeBy(4, append) + U.deepStrictEqual(await pipe(as, _.traverseReadonlyArrayWithIndex(SK))(undefined)(), [0, 1, 2, 3]) + U.deepStrictEqual(log, [0, 2, 1, 3]) + }) + + it('sequenceReadonlyArraySeq', async () => { + U.deepStrictEqual(await pipe(RA.empty, _.traverseReadonlyArrayWithIndexSeq(SK))(undefined)(), RA.empty) + const log: Array = [] + const append = (n: number): _.ReaderTask => + _.fromTask( + T.delay(n % 2 === 0 ? 50 : 100)( + T.fromIO(() => { + log.push(n) + return n + }) + ) + ) + const as = RA.makeBy(4, append) + U.deepStrictEqual(await pipe(as, _.traverseReadonlyArrayWithIndexSeq(SK))(undefined)(), [0, 1, 2, 3]) + U.deepStrictEqual(log, [0, 1, 2, 3]) + }) + + // old + it('sequenceArray', async () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const append = (n: number): _.ReaderTask => + _.fromTask( + T.delay(n % 2 === 0 ? 50 : 100)( + T.fromIO(() => { + log.push(n) + return n + }) + ) ) - ) - const as = RA.makeBy(4, append) - U.deepStrictEqual(await pipe(as, _.sequenceArray)(undefined)(), [0, 1, 2, 3]) - U.deepStrictEqual(log, [0, 2, 1, 3]) - }) - - it('sequenceSeqArray', async () => { - // tslint:disable-next-line: readonly-array - const log: Array = [] - const append = (n: number): _.ReaderTask => - _.fromTask( - T.delay(n % 2 === 0 ? 50 : 100)( - T.fromIO(() => { - log.push(n) - return n - }) + const as = RA.makeBy(4, append) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe(as, _.sequenceArray)(undefined)(), [0, 1, 2, 3]) + U.deepStrictEqual(log, [0, 2, 1, 3]) + }) + + it('sequenceSeqArray', async () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const append = (n: number): _.ReaderTask => + _.fromTask( + T.delay(n % 2 === 0 ? 50 : 100)( + T.fromIO(() => { + log.push(n) + return n + }) + ) ) - ) - const as = RA.makeBy(4, append) - U.deepStrictEqual(await pipe(as, _.sequenceSeqArray)(undefined)(), [0, 1, 2, 3]) - U.deepStrictEqual(log, [0, 1, 2, 3]) + const as = RA.makeBy(4, append) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe(as, _.sequenceSeqArray)(undefined)(), [0, 1, 2, 3]) + U.deepStrictEqual(log, [0, 1, 2, 3]) + }) }) }) diff --git a/test/ReaderTaskEither.ts b/test/ReaderTaskEither.ts index 1267bf984..e9d94ee09 100644 --- a/test/ReaderTaskEither.ts +++ b/test/ReaderTaskEither.ts @@ -1,7 +1,6 @@ -import * as U from './util' import { sequenceT } from '../src/Apply' import * as E from '../src/Either' -import { pipe } from '../src/function' +import { flow, pipe, SK } from '../src/function' import * as I from '../src/IO' import * as IE from '../src/IOEither' import * as N from '../src/number' @@ -10,10 +9,13 @@ import * as R from '../src/Reader' import * as RE from '../src/ReaderEither' import * as RT from '../src/ReaderTask' import * as _ from '../src/ReaderTaskEither' +import * as RA from '../src/ReadonlyArray' +import { ReadonlyNonEmptyArray } from '../src/ReadonlyNonEmptyArray' +import { left, right } from '../src/Separated' import * as S from '../src/string' import * as T from '../src/Task' import * as TE from '../src/TaskEither' -import { left, right } from '../src/Separated' +import * as U from './util' describe('ReaderTaskEither', () => { describe('pipeables', () => { @@ -53,6 +55,21 @@ describe('ReaderTaskEither', () => { U.deepStrictEqual(await pipe(_.right(_.right('a')), _.flatten)({})(), E.right('a')) }) + type R1 = { readonly env1: unknown } + type R2 = { readonly env2: unknown } + type E1 = { readonly left1: unknown } + type E2 = { readonly left2: unknown } + + it('flattenW', async () => { + U.deepStrictEqual( + await pipe( + _.right>(_.right('a')), + _.flattenW + )({ env1: '', env2: '' })(), + E.right('a') + ) + }) + it('bimap', async () => { const f = (s: string): number => s.length const g = (n: number): boolean => n > 2 @@ -163,7 +180,6 @@ describe('ReaderTaskEither', () => { U.deepStrictEqual( await pipe( _.asks((n: number) => n + 1), - // tslint:disable-next-line: deprecation _.local(S.size) )('aaa')(), E.right(4) @@ -250,6 +266,43 @@ describe('ReaderTaskEither', () => { ) }) + it('orElseW', async () => { + U.deepStrictEqual( + await pipe( + _.right(1), + _.orElseW((s: string) => _.right(s.length)) + )({})(), + E.right(1) + ) + U.deepStrictEqual( + await pipe( + _.left('error'), + _.orElseW((s) => _.right(s.length)) + )({})(), + E.right(5) + ) + }) + + it('orElseFirst', async () => { + const f = _.orElseFirst((s: string) => (s.length <= 1 ? _.right(true) : _.left(s + '!'))) + U.deepStrictEqual(await pipe(_.right(1), f)({})(), E.right(1)) + U.deepStrictEqual(await pipe(_.left('a'), f)({})(), E.left('a')) + U.deepStrictEqual(await pipe(_.left('aa'), f)({})(), E.left('aa!')) + }) + + it('orElseFirstW', async () => { + const f = _.orElseFirstW((s: string) => (s.length <= 1 ? _.right(true) : _.left(s + '!'))) + U.deepStrictEqual(await pipe(_.right(1), f)({})(), E.right(1)) + U.deepStrictEqual(await pipe(_.left('a'), f)({})(), E.left('a')) + U.deepStrictEqual(await pipe(_.left('aa'), f)({})(), E.left('aa!')) + }) + + it('orLeft', async () => { + const f = _.orLeft((s: string) => RT.of(s + '!')) + U.deepStrictEqual(await pipe(_.right(1), f)({})(), E.right(1)) + U.deepStrictEqual(await pipe(_.left('a'), f)({})(), E.left('a!')) + }) + describe('MonadIO', () => { it('fromIO', async () => { U.deepStrictEqual(await _.fromIO(() => 1)({})(), E.right(1)) @@ -377,6 +430,36 @@ describe('ReaderTaskEither', () => { U.deepStrictEqual(await pipe(_.right('a'), _.chainTaskEitherK(f))(undefined)(), E.right(1)) }) + it('chainFirstTaskEitherKW', async () => { + const f = (s: string) => TE.right(s.length) + U.deepStrictEqual(await pipe(_.right<{}, number, string>('a'), _.chainFirstTaskEitherKW(f))({})(), E.right('a')) + }) + + it('chainReaderTaskK', async () => { + const f = flow(S.size, RT.of) + U.deepStrictEqual(await pipe(_.right('a'), _.chainReaderTaskK(f))(undefined)(), E.right(1)) + }) + + it('chainReaderTaskKW', async () => { + const f = flow(S.size, RT.of) + U.deepStrictEqual(await pipe(_.right<{}, never, string>('a'), _.chainReaderTaskKW(f))({})(), E.right(1)) + }) + + it('chainFirstReaderTaskKW', async () => { + const f = flow(S.size, RT.of) + U.deepStrictEqual(await pipe(_.right<{}, never, string>('a'), _.chainFirstReaderTaskKW(f))({})(), E.right('a')) + }) + + it('chainReaderEitherKW', async () => { + const f = (s: string) => RE.right(s.length) + U.deepStrictEqual(await pipe(_.right<{}, never, string>('a'), _.chainReaderEitherKW(f))({})(), E.right(1)) + }) + + it('chainFirstReaderEitherKW', async () => { + const f = (s: string) => RE.right(s.length) + U.deepStrictEqual(await pipe(_.right<{}, never, string>('a'), _.chainFirstReaderEitherKW(f))({})(), E.right('a')) + }) + // ------------------------------------------------------------------------------------- // utils // ------------------------------------------------------------------------------------- @@ -399,42 +482,121 @@ describe('ReaderTaskEither', () => { ) }) - it('sequenceArray', async () => { - // tslint:disable-next-line: readonly-array - const log: Array = [] - const right = (n: number): _.ReaderTaskEither => - _.rightIO(() => { - log.push(n) - return n - }) - const left = (s: string): _.ReaderTaskEither => - _.leftIO(() => { - log.push(s) - return s - }) - U.deepStrictEqual(await pipe([right(1), right(2)], _.sequenceArray)(undefined)(), E.right([1, 2])) - U.deepStrictEqual(await pipe([right(3), left('a')], _.sequenceArray)(undefined)(), E.left('a')) - U.deepStrictEqual(await pipe([left('b'), right(4)], _.sequenceArray)(undefined)(), E.left('b')) - U.deepStrictEqual(log, [1, 2, 3, 'a', 'b', 4]) - }) + describe('array utils', () => { + const input: ReadonlyNonEmptyArray = ['a', 'b'] - it('sequenceSeqArray', async () => { - // tslint:disable-next-line: readonly-array - const log: Array = [] - const right = (n: number): _.ReaderTaskEither => - _.rightIO(() => { - log.push(n) - return n - }) - const left = (s: string): _.ReaderTaskEither => - _.leftIO(() => { - log.push(s) - return s - }) - U.deepStrictEqual(await pipe([right(1), right(2)], _.sequenceSeqArray)(undefined)(), E.right([1, 2])) - U.deepStrictEqual(await pipe([right(3), left('a')], _.sequenceSeqArray)(undefined)(), E.left('a')) - U.deepStrictEqual(await pipe([left('b'), right(4)], _.sequenceSeqArray)(undefined)(), E.left('b')) - U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + it('traverseReadonlyArrayWithIndex', async () => { + const f = _.traverseReadonlyArrayWithIndex((i, a: string) => (a.length > 0 ? _.right(a + i) : _.left('e'))) + U.deepStrictEqual(await pipe(RA.empty, f)(undefined)(), E.right(RA.empty)) + U.deepStrictEqual(await pipe(input, f)(undefined)(), E.right(['a0', 'b1'])) + U.deepStrictEqual(await pipe(['a', ''], f)(undefined)(), E.left('e')) + }) + + it('traverseReadonlyArrayWithIndexSeq', async () => { + const f = _.traverseReadonlyArrayWithIndexSeq((i, a: string) => (a.length > 0 ? _.right(a + i) : _.left('e'))) + U.deepStrictEqual(await pipe(RA.empty, f)(undefined)(), E.right(RA.empty)) + U.deepStrictEqual(await pipe(input, f)(undefined)(), E.right(['a0', 'b1'])) + U.deepStrictEqual(await pipe(['a', ''], f)(undefined)(), E.left('e')) + }) + + it('sequenceReadonlyArray', async () => { + const log: Array = [] + const right = (n: number): _.ReaderTaskEither => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.ReaderTaskEither => + _.leftIO(() => { + log.push(s) + return s + }) + U.deepStrictEqual( + await pipe([right(1), right(2)], _.traverseReadonlyArrayWithIndex(SK))(undefined)(), + E.right([1, 2]) + ) + U.deepStrictEqual( + await pipe([right(3), left('a')], _.traverseReadonlyArrayWithIndex(SK))(undefined)(), + E.left('a') + ) + U.deepStrictEqual( + await pipe([left('b'), right(4)], _.traverseReadonlyArrayWithIndex(SK))(undefined)(), + E.left('b') + ) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b', 4]) + }) + + it('sequenceReadonlyArraySeq', async () => { + const log: Array = [] + const right = (n: number): _.ReaderTaskEither => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.ReaderTaskEither => + _.leftIO(() => { + log.push(s) + return s + }) + U.deepStrictEqual( + await pipe([right(1), right(2)], _.traverseReadonlyArrayWithIndexSeq(SK))(undefined)(), + E.right([1, 2]) + ) + U.deepStrictEqual( + await pipe([right(3), left('a')], _.traverseReadonlyArrayWithIndexSeq(SK))(undefined)(), + E.left('a') + ) + U.deepStrictEqual( + await pipe([left('b'), right(4)], _.traverseReadonlyArrayWithIndexSeq(SK))(undefined)(), + E.left('b') + ) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + }) + + // old + it('sequenceArray', async () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const right = (n: number): _.ReaderTaskEither => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.ReaderTaskEither => + _.leftIO(() => { + log.push(s) + return s + }) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([right(1), right(2)], _.sequenceArray)(undefined)(), E.right([1, 2])) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([right(3), left('a')], _.sequenceArray)(undefined)(), E.left('a')) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([left('b'), right(4)], _.sequenceArray)(undefined)(), E.left('b')) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b', 4]) + }) + + it('sequenceSeqArray', async () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const right = (n: number): _.ReaderTaskEither => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.ReaderTaskEither => + _.leftIO(() => { + log.push(s) + return s + }) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([right(1), right(2)], _.sequenceSeqArray)(undefined)(), E.right([1, 2])) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([right(3), left('a')], _.sequenceSeqArray)(undefined)(), E.left('a')) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([left('b'), right(4)], _.sequenceSeqArray)(undefined)(), E.left('b')) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + }) }) it('getCompactable', async () => { diff --git a/test/ReadonlyArray.ts b/test/ReadonlyArray.ts index a96be5918..68205872c 100644 --- a/test/ReadonlyArray.ts +++ b/test/ReadonlyArray.ts @@ -4,12 +4,14 @@ import { isDeepStrictEqual } from 'util' import * as B from '../src/boolean' import * as E from '../src/Either' import * as Eq from '../src/Eq' -import { identity, pipe, Predicate, tuple } from '../src/function' +import { identity, pipe, tuple } from '../src/function' import * as M from '../src/Monoid' import * as N from '../src/number' import * as O from '../src/Option' import * as Ord from '../src/Ord' +import { Predicate } from '../src/Predicate' import * as _ from '../src/ReadonlyArray' +import { Refinement } from '../src/Refinement' import { separated } from '../src/Separated' import * as S from '../src/string' import * as T from '../src/Task' @@ -1040,6 +1042,16 @@ describe('ReadonlyArray', () => { }) }) + it('prepend', () => { + U.deepStrictEqual(pipe(['a', 'b'], _.prepend('c')), ['c', 'a', 'b']) + U.deepStrictEqual(pipe(['a', 'b'], _.prependW(3)), [3, 'a', 'b']) + }) + + it('append', () => { + U.deepStrictEqual(pipe(['a', 'b'], _.append('c')), ['a', 'b', 'c']) + U.deepStrictEqual(pipe(['a', 'b'], _.appendW(3)), ['a', 'b', 3]) + }) + it('makeBy', () => { U.deepStrictEqual(_.makeBy(5, U.double), [0, 2, 4, 6, 8]) U.strictEqual(_.makeBy(0, U.double), _.empty) @@ -1055,14 +1067,22 @@ describe('ReadonlyArray', () => { }) it('range', () => { + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(0, 0), [0]) + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(0, 1), [0, 1]) + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(1, 5), [1, 2, 3, 4, 5]) + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(10, 15), [10, 11, 12, 13, 14, 15]) + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(-1, 0), [-1, 0]) + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(-5, -1), [-5, -4, -3, -2, -1]) // out of bound + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(2, 1), [2]) + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.range(-1, -2), [-1]) }) @@ -1139,6 +1159,32 @@ describe('ReadonlyArray', () => { U.deepStrictEqual(pipe([1, 2], _.difference(N.Eq)([1, 2])), []) }) + it('getUnionMonoid', () => { + const M = _.getUnionMonoid(N.Eq) + const two: ReadonlyArray = [1, 2] + U.deepStrictEqual(M.concat(two, [3, 4]), [1, 2, 3, 4]) + U.deepStrictEqual(M.concat(two, [2, 3]), [1, 2, 3]) + U.deepStrictEqual(M.concat(two, [1, 2]), [1, 2]) + + U.strictEqual(M.concat(two, M.empty), two) + U.strictEqual(M.concat(M.empty, two), two) + U.strictEqual(M.concat(M.empty, M.empty), M.empty) + }) + + it('getIntersectionSemigroup', () => { + const concat = _.getIntersectionSemigroup(N.Eq).concat + U.deepStrictEqual(concat([1, 2], [3, 4]), []) + U.deepStrictEqual(concat([1, 2], [2, 3]), [2]) + U.deepStrictEqual(concat([1, 2], [1, 2]), [1, 2]) + }) + + it('getDifferenceMagma', () => { + const concat = _.getDifferenceMagma(N.Eq).concat + U.deepStrictEqual(concat([1, 2], [3, 4]), [1, 2]) + U.deepStrictEqual(concat([1, 2], [2, 3]), [1]) + U.deepStrictEqual(concat([1, 2], [1, 2]), []) + }) + it('should be safe when calling map with a binary function', () => { interface Foo { readonly bar: () => number @@ -1210,4 +1256,185 @@ describe('ReadonlyArray', () => { U.deepStrictEqual(_.size([]), 0) U.deepStrictEqual(_.size(['a']), 1) }) + + describe('chainRec', () => { + it('depth-first', () => { + const chainRec = _.ChainRecDepthFirst.chainRec + assert.deepStrictEqual( + chainRec(1, () => []), + [] + ) + assert.deepStrictEqual( + chainRec(1, () => [E.right('foo')]), + ['foo'] + ) + assert.deepStrictEqual( + chainRec(1, (a) => { + if (a < 5) { + return [E.right(a), E.left(a + 1)] + } else { + return [E.right(a)] + } + }), + [1, 2, 3, 4, 5] + ) + assert.deepStrictEqual( + chainRec(1, (a) => { + if (a < 5) { + return [E.left(a + 1), E.right(a)] + } else { + return [E.right(a)] + } + }), + [5, 4, 3, 2, 1] + ) + assert.deepStrictEqual( + chainRec(1, (a) => { + if (a < 5) { + return a % 2 === 0 ? [E.right(a), E.left(a + 1)] : [E.left(a + 1), E.right(a)] + } else { + return [E.right(a)] + } + }), + [2, 4, 5, 3, 1] + ) + assert.deepStrictEqual( + chainRec(0, (a) => { + if (a === 0) { + return [E.right(a), E.left(a - 1), E.left(a + 1)] + } else if (0 < a && a < 5) { + return [E.right(a), E.left(a + 1)] + } else if (-5 < a && a < 0) { + return [E.right(a), E.left(a - 1)] + } else { + return [E.right(a)] + } + }), + [0, -1, -2, -3, -4, -5, 1, 2, 3, 4, 5] + ) + assert.deepStrictEqual( + chainRec(0, (a) => { + if (a === 0) { + return [E.left(a - 1), E.right(a), E.left(a + 1)] + } else if (0 < a && a < 5) { + return [E.right(a), E.left(a + 1)] + } else if (-5 < a && a < 0) { + return [E.left(a - 1), E.right(a)] + } else { + return [E.right(a)] + } + }), + [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5] + ) + }) + it('breadth-first', () => { + const chainRec = _.ChainRecBreadthFirst.chainRec + assert.deepStrictEqual( + chainRec(1, () => []), + [] + ) + assert.deepStrictEqual( + chainRec(1, () => [E.right('foo')]), + ['foo'] + ) + assert.deepStrictEqual( + chainRec(1, (a) => { + if (a < 5) { + return [E.right(a), E.left(a + 1)] + } else { + return [E.right(a)] + } + }), + [1, 2, 3, 4, 5] + ) + assert.deepStrictEqual( + chainRec(1, (a) => { + if (a < 5) { + return [E.left(a + 1), E.right(a)] + } else { + return [E.right(a)] + } + }), + [1, 2, 3, 4, 5] + ) + assert.deepStrictEqual( + chainRec(0, (a) => { + if (a === 0) { + return [E.right(a), E.left(a - 1), E.left(a + 1)] + } else if (0 < a && a < 5) { + return [E.right(a), E.left(a + 1)] + } else if (-5 < a && a < 0) { + return [E.right(a), E.left(a - 1)] + } else { + return [E.right(a)] + } + }), + [0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5] + ) + assert.deepStrictEqual( + chainRec(0, (a) => { + if (a === 0) { + return [E.left(a - 1), E.right(a), E.left(a + 1)] + } else if (0 < a && a < 5) { + return [E.right(a), E.left(a + 1)] + } else if (-5 < a && a < 0) { + return [E.left(a - 1), E.right(a)] + } else { + return [E.right(a)] + } + }), + [0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5] + ) + }) + }) + + describe('fromPredicate', () => { + it('can create an array from a Refinement', () => { + const refinement: Refinement = (a): a is string => typeof a === 'string' + U.deepStrictEqual(_.fromPredicate(refinement)('hello'), ['hello']) + U.deepStrictEqual(_.fromPredicate(refinement)(null), []) + }) + + it('can create an array from a Predicate', () => { + const predicate = (a: string) => a.length > 0 + U.deepStrictEqual(_.fromPredicate(predicate)('hi'), ['hi']) + U.deepStrictEqual(_.fromPredicate(predicate)(''), []) + }) + }) + + it('fromOption', () => { + U.deepStrictEqual(_.fromOption(O.some('hello')), ['hello']) + U.deepStrictEqual(_.fromOption(O.none), []) + }) + + it('fromEither', () => { + U.deepStrictEqual(_.fromEither(E.right(1)), [1]) + U.strictEqual(_.fromEither(E.left('a')), _.empty) + }) + + it('match', () => { + const f = _.match( + () => 'empty', + (as) => `nonEmpty ${as.length}` + ) + U.deepStrictEqual(pipe(_.empty, f), 'empty') + U.deepStrictEqual(pipe([1, 2, 3], f), 'nonEmpty 3') + }) + + it('concatW', () => { + U.deepStrictEqual(pipe([1], _.concatW(['a'])), [1, 'a']) + const as = [1, 2, 3] + U.strictEqual(pipe(_.empty, _.concatW(as)), as) + U.strictEqual(pipe(as, _.concatW(_.empty)), as) + const empty: ReadonlyArray = [] + U.strictEqual(pipe(empty, _.concatW(as)), as) + U.strictEqual(pipe(as, _.concatW(empty)), as) + }) + + it('fromOptionK', () => { + const f = (n: number) => (n > 0 ? O.some(n) : O.none) + const g = _.fromOptionK(f) + U.strictEqual(g(0), _.empty) + U.deepStrictEqual(g(1), [1]) + }) }) diff --git a/test/ReadonlyMap.ts b/test/ReadonlyMap.ts index 6feb48f11..ea6a24388 100644 --- a/test/ReadonlyMap.ts +++ b/test/ReadonlyMap.ts @@ -1,16 +1,17 @@ import * as assert from 'assert' import { Either, left, right } from '../src/Either' import { Eq, fromEquals } from '../src/Eq' -import { identity, pipe, Refinement } from '../src/function' +import { identity, pipe } from '../src/function' import * as IO from '../src/IO' import * as N from '../src/number' import * as O from '../src/Option' import * as Ord from '../src/Ord' import * as RA from '../src/ReadonlyArray' import * as _ from '../src/ReadonlyMap' +import { Refinement } from '../src/Refinement' import * as Se from '../src/Semigroup' import { separated } from '../src/Separated' -import { struct, Show } from '../src/Show' +import { Show, struct } from '../src/Show' import * as S from '../src/string' import * as T from '../src/Task' import * as U from './util' @@ -1156,4 +1157,81 @@ describe('ReadonlyMap', () => { aa3 ) }) + + it('getUnionMonoid', () => { + const M = _.getUnionMonoid(eqUser, S.Semigroup) + const x = new Map([ + [{ id: 'a' }, 'a1'], + [{ id: 'b' }, 'b1'], + [{ id: 'c' }, 'c1'] + ]) + const y = new Map([ + [{ id: 'b' }, 'b2'], + [{ id: 'c' }, 'c2'], + [{ id: 'd' }, 'd2'] + ]) + U.strictEqual(M.concat(x, M.empty), x) + U.strictEqual(M.concat(M.empty, x), x) + U.strictEqual(M.concat(x, new Map()), x) + U.strictEqual(M.concat(new Map(), x), x) + U.deepStrictEqual( + M.concat(x, y), + new Map([ + [{ id: 'a' }, 'a1'], + [{ id: 'b' }, 'b1b2'], + [{ id: 'c' }, 'c1c2'], + [{ id: 'd' }, 'd2'] + ]) + ) + }) + + it('getIntersectionSemigroup', () => { + const M = _.getIntersectionSemigroup(eqUser, S.Semigroup) + const x = new Map([ + [{ id: 'a' }, 'a1'], + [{ id: 'b' }, 'b1'], + [{ id: 'c' }, 'c1'] + ]) + const y = new Map([ + [{ id: 'b' }, 'b2'], + [{ id: 'c' }, 'c2'], + [{ id: 'd' }, 'd2'] + ]) + U.strictEqual(M.concat(x, _.empty), _.empty) + U.strictEqual(M.concat(_.empty, x), _.empty) + U.strictEqual(M.concat(x, new Map()), _.empty) + U.strictEqual(M.concat(new Map(), x), _.empty) + U.deepStrictEqual( + M.concat(x, y), + new Map([ + [{ id: 'b' }, 'b1b2'], + [{ id: 'c' }, 'c1c2'] + ]) + ) + }) + + it('getDifferenceMagma', () => { + const M = _.getDifferenceMagma(eqUser)() + const x = new Map([ + [{ id: 'a' }, 'a1'], + [{ id: 'b' }, 'b1'], + [{ id: 'c' }, 'c1'] + ]) + const y = new Map([ + [{ id: 'b' }, 'b2'], + [{ id: 'c' }, 'c2'], + [{ id: 'd' }, 'd2'] + ]) + U.strictEqual(M.concat(x, _.empty), x) + U.strictEqual(M.concat(_.empty, x), x) + U.strictEqual(M.concat(x, new Map()), x) + U.strictEqual(M.concat(new Map(), x), x) + U.deepStrictEqual( + M.concat(x, y), + new Map([ + [{ id: 'a' }, 'a1'], + [{ id: 'd' }, 'd2'] + ]) + ) + }) }) diff --git a/test/ReadonlyNonEmptyArray.ts b/test/ReadonlyNonEmptyArray.ts index e810de356..b9c957758 100644 --- a/test/ReadonlyNonEmptyArray.ts +++ b/test/ReadonlyNonEmptyArray.ts @@ -1,5 +1,6 @@ import * as assert from 'assert' import * as B from '../src/boolean' +import { Endomorphism } from '../src/Endomorphism' import * as Eq from '../src/Eq' import { identity, pipe } from '../src/function' import * as N from '../src/number' @@ -160,7 +161,9 @@ describe('ReadonlyNonEmptyArray', () => { }) it('groupSort', () => { + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.groupSort(N.Ord)([]), []) + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.groupSort(N.Ord)([1, 2, 1, 1]), [[1, 1, 1], [2]]) }) @@ -364,8 +367,7 @@ describe('ReadonlyNonEmptyArray', () => { U.deepStrictEqual(Sh.show(['a', 'b', 'c']), `["a", "b", "c"]`) }) - it('alt / concat', () => { - U.deepStrictEqual(_.concat(['a'], []), ['a']) + it('alt', () => { U.deepStrictEqual( pipe( ['a'], @@ -608,16 +610,98 @@ describe('ReadonlyNonEmptyArray', () => { }) it('union', () => { - const concat = _.union(N.Eq) + const concat = _.getUnionSemigroup(N.Eq).concat U.deepStrictEqual(concat([1, 2], [3, 4]), [1, 2, 3, 4]) U.deepStrictEqual(concat([1, 2], [2, 3]), [1, 2, 3]) U.deepStrictEqual(concat([1, 2], [1, 2]), [1, 2]) }) + it('matchLeft', () => { + U.deepStrictEqual( + pipe( + [1, 2, 3], + _.matchLeft((head, tail) => [head, tail]) + ), + [1, [2, 3]] + ) + }) + + it('matchRight', () => { + U.deepStrictEqual( + pipe( + [1, 2, 3], + _.matchRight((init, last) => [init, last]) + ), + [[1, 2], 3] + ) + }) + + it('modifyHead', () => { + const f: Endomorphism = (s) => s + '!' + U.deepStrictEqual(pipe(['a'], _.modifyHead(f)), ['a!']) + U.deepStrictEqual(pipe(['a', 'b'], _.modifyHead(f)), ['a!', 'b']) + U.deepStrictEqual(pipe(['a', 'b', 'c'], _.modifyHead(f)), ['a!', 'b', 'c']) + }) + + it('modifyLast', () => { + const f: Endomorphism = (s) => s + '!' + U.deepStrictEqual(pipe(['a'], _.modifyLast(f)), ['a!']) + U.deepStrictEqual(pipe(['a', 'b'], _.modifyLast(f)), ['a', 'b!']) + U.deepStrictEqual(pipe(['a', 'b', 'c'], _.modifyLast(f)), ['a', 'b', 'c!']) + }) + it('makeBy', () => { - U.deepStrictEqual(_.makeBy(5, U.double), [0, 2, 4, 6, 8]) + const f = _.makeBy(U.double) + U.deepStrictEqual(f(5), [0, 2, 4, 6, 8]) // If `n` (must be a natural number) is non positive return `[f(0)]`. - U.deepStrictEqual(_.makeBy(0, U.double), [0]) - U.deepStrictEqual(_.makeBy(-1, U.double), [0]) + U.deepStrictEqual(f(0), [0]) + U.deepStrictEqual(f(-1), [0]) + }) + + it('range', () => { + U.deepStrictEqual(_.range(0, 0), [0]) + U.deepStrictEqual(_.range(0, 1), [0, 1]) + U.deepStrictEqual(_.range(1, 5), [1, 2, 3, 4, 5]) + U.deepStrictEqual(_.range(10, 15), [10, 11, 12, 13, 14, 15]) + U.deepStrictEqual(_.range(-1, 0), [-1, 0]) + U.deepStrictEqual(_.range(-5, -1), [-5, -4, -3, -2, -1]) + // out of bound + U.deepStrictEqual(_.range(2, 1), [2]) + U.deepStrictEqual(_.range(-1, -2), [-1]) + }) + + it('replicate', () => { + const f = _.replicate('a') + U.deepStrictEqual(pipe(0, f), ['a']) + U.deepStrictEqual(pipe(1, f), ['a']) + U.deepStrictEqual(pipe(2, f), ['a', 'a']) + }) + + it('updateHead', () => { + U.deepStrictEqual(pipe(['a'], _.updateHead('d')), ['d']) + U.deepStrictEqual(pipe(['a', 'b'], _.updateHead('d')), ['d', 'b']) + U.deepStrictEqual(pipe(['a', 'b', 'c'], _.updateHead('d')), ['d', 'b', 'c']) + }) + + it('updateLast', () => { + U.deepStrictEqual(pipe(['a'], _.updateLast('d')), ['d']) + U.deepStrictEqual(pipe(['a', 'b'], _.updateLast('d')), ['a', 'd']) + U.deepStrictEqual(pipe(['a', 'b', 'c'], _.updateLast('d')), ['a', 'b', 'd']) + }) + + it('concatW', () => { + U.deepStrictEqual(pipe(['a'], _.concatW(['b'])), ['a', 'b']) + }) + + it('concat', () => { + U.deepStrictEqual(pipe(['a'], _.concat(['b'])), ['a', 'b']) + U.deepStrictEqual(pipe(_.empty, _.concat(['b'])), ['b']) + U.deepStrictEqual(pipe(['a'], _.concat(_.empty)), ['a']) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(_.concat(['a'], ['b']), ['a', 'b']) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(_.concat(['a'], _.empty), ['a']) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(_.concat(_.empty, ['b']), ['b']) }) }) diff --git a/test/ReadonlyRecord.ts b/test/ReadonlyRecord.ts index 9afd52355..abbe8cca5 100644 --- a/test/ReadonlyRecord.ts +++ b/test/ReadonlyRecord.ts @@ -4,6 +4,7 @@ import { identity, pipe } from '../src/function' import * as IO from '../src/IO' import * as N from '../src/number' import * as O from '../src/Option' +import { reverse } from '../src/Ord' import * as RA from '../src/ReadonlyArray' import * as _ from '../src/ReadonlyRecord' import * as Se from '../src/Semigroup' @@ -18,6 +19,19 @@ const noPrototype = Object.create(null) describe('ReadonlyRecord', () => { describe('pipeables', () => { + it('collect', () => { + const x: { readonly a: string; readonly b: boolean } = { a: 'c', b: false } + U.deepStrictEqual(_.collect(S.Ord)((key, val) => ({ key: key, value: val }))(x), [ + { key: 'a', value: 'c' }, + { key: 'b', value: false } + ]) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(_.collect((key, val) => ({ key: key, value: val }))(x), [ + { key: 'a', value: 'c' }, + { key: 'b', value: false } + ]) + }) + it('map', () => { U.deepStrictEqual(pipe({ k1: 1, k2: 2 }, _.map(U.double)), { k1: 2, k2: 4 }) U.deepStrictEqual(pipe({ a: 1, b: 2 }, _.map(U.double)), { a: 2, b: 4 }) @@ -28,6 +42,21 @@ describe('ReadonlyRecord', () => { U.deepStrictEqual( pipe( { k1: 'a', k2: 'b' }, + _.reduce(S.Ord)('', (b, a) => b + a) + ), + 'ab' + ) + U.deepStrictEqual( + pipe( + { k2: 'b', k1: 'a' }, + _.reduce(S.Ord)('', (b, a) => b + a) + ), + 'ab' + ) + U.deepStrictEqual( + pipe( + { k1: 'a', k2: 'b' }, + // tslint:disable-next-line: deprecation _.reduce('', (b, a) => b + a) ), 'ab' @@ -35,6 +64,7 @@ describe('ReadonlyRecord', () => { U.deepStrictEqual( pipe( { k2: 'b', k1: 'a' }, + // tslint:disable-next-line: deprecation _.reduce('', (b, a) => b + a) ), 'ab' @@ -42,11 +72,20 @@ describe('ReadonlyRecord', () => { }) it('foldMap', () => { + U.deepStrictEqual(pipe({ a: 'a', b: 'b' }, _.foldMap(S.Ord)(S.Monoid)(identity)), 'ab') + U.deepStrictEqual(_.getFoldable(S.Ord).foldMap(S.Monoid)({ a: 'a', b: 'b' }, identity), 'ab') + + // tslint:disable-next-line: deprecation U.deepStrictEqual(pipe({ a: 'a', b: 'b' }, _.foldMap(S.Monoid)(identity)), 'ab') + // tslint:disable-next-line: deprecation + U.deepStrictEqual(_.Foldable.foldMap(S.Monoid)({ a: 'a', b: 'b' }, identity), 'ab') }) it('reduceRight', () => { const f = (a: string, acc: string) => acc + a + U.deepStrictEqual(pipe({ a: 'a', b: 'b' }, _.reduceRight(S.Ord)('', f)), 'ba') + + // tslint:disable-next-line: deprecation U.deepStrictEqual(pipe({ a: 'a', b: 'b' }, _.reduceRight('', f)), 'ba') }) @@ -107,6 +146,22 @@ describe('ReadonlyRecord', () => { U.deepStrictEqual( pipe( { k1: 'a', k2: 'b' }, + _.reduceWithIndex(S.Ord)('', (k, b, a) => b + k + a) + ), + 'k1ak2b' + ) + U.deepStrictEqual( + pipe( + { k2: 'b', k1: 'a' }, + _.reduceWithIndex(S.Ord)('', (k, b, a) => b + k + a) + ), + 'k1ak2b' + ) + + U.deepStrictEqual( + pipe( + { k1: 'a', k2: 'b' }, + // tslint:disable-next-line: deprecation _.reduceWithIndex('', (k, b, a) => b + k + a) ), 'k1ak2b' @@ -114,6 +169,7 @@ describe('ReadonlyRecord', () => { U.deepStrictEqual( pipe( { k2: 'b', k1: 'a' }, + // tslint:disable-next-line: deprecation _.reduceWithIndex('', (k, b, a) => b + k + a) ), 'k1ak2b' @@ -124,16 +180,42 @@ describe('ReadonlyRecord', () => { U.deepStrictEqual( pipe( { k1: 'a', k2: 'b' }, + _.foldMapWithIndex(S.Ord)(S.Monoid)((k, a) => k + a) + ), + 'k1ak2b' + ) + U.deepStrictEqual( + _.getFoldableWithIndex(S.Ord).foldMapWithIndex(S.Monoid)({ k1: 'a', k2: 'b' }, (k, a) => k + a), + 'k1ak2b' + ) + + U.deepStrictEqual( + pipe( + { k1: 'a', k2: 'b' }, + // tslint:disable-next-line: deprecation _.foldMapWithIndex(S.Monoid)((k, a) => k + a) ), 'k1ak2b' ) + U.deepStrictEqual( + // tslint:disable-next-line: deprecation + _.FoldableWithIndex.foldMapWithIndex(S.Monoid)({ k1: 'a', k2: 'b' }, (k, a) => k + a), + 'k1ak2b' + ) }) it('reduceRightWithIndex', () => { U.deepStrictEqual( pipe( { k1: 'a', k2: 'b' }, + _.reduceRightWithIndex(S.Ord)('', (k, a, b) => b + k + a) + ), + 'k2bk1a' + ) + U.deepStrictEqual( + pipe( + { k1: 'a', k2: 'b' }, + // tslint:disable-next-line: deprecation _.reduceRightWithIndex('', (k, a, b) => b + k + a) ), 'k2bk1a' @@ -182,24 +264,57 @@ describe('ReadonlyRecord', () => { U.deepStrictEqual(_.traverse(O.Applicative)((n: number) => (n >= 2 ? O.some(n) : O.none))({ a: 1, b: 2 }), O.none) }) + it('getTraversable', () => { + const T = _.getTraversable(reverse(S.Ord)) + const f = (n: number) => (n <= 2 ? O.some(n) : O.none) + U.deepStrictEqual(T.traverse(O.Applicative)({ a: 1, b: 2 }, f), O.some({ a: 1, b: 2 })) + U.deepStrictEqual(T.traverse(O.Applicative)({ a: 1, b: 3 }, f), O.none) + // should respect the order + U.deepStrictEqual(pipe(T.traverse(O.Applicative)({ b: 2, a: 1 }, f), O.map(Object.keys)), O.some(['b', 'a'])) + U.deepStrictEqual( + pipe(T.sequence(O.Applicative)({ b: O.some(2), a: O.some(1) }), O.map(Object.keys)), + O.some(['b', 'a']) + ) + }) + it('sequence', () => { const sequence = _.sequence(O.Applicative) U.deepStrictEqual(sequence({ a: O.some(1), b: O.some(2) }), O.some({ a: 1, b: 2 })) U.deepStrictEqual(sequence({ a: O.none, b: O.some(2) }), O.none) + + U.deepStrictEqual( + // tslint:disable-next-line: deprecation + _.readonlyRecord.sequence(O.Applicative)({ a: O.some(1), b: O.some(2) }), + O.some({ a: 1, b: 2 }) + ) }) it('traverseWithIndex', () => { - const traverseWithIndex = _.traverseWithIndex(O.Applicative)( - (k, n: number): O.Option => (k !== 'a' ? O.some(n) : O.none) - ) + const f = (k: string, n: number): O.Option => (k !== 'a' ? O.some(n) : O.none) + const traverseWithIndex = _.traverseWithIndex(O.Applicative)(f) U.deepStrictEqual(pipe({ a: 1, b: 2 }, traverseWithIndex), O.none) U.deepStrictEqual(pipe({ b: 2 }, traverseWithIndex), O.some({ b: 2 })) }) + it('getTraversableWithIndex', () => { + const TWI = _.getTraversableWithIndex(reverse(S.Ord)) + const f = (k: string, n: number): O.Option => (k !== 'a' ? O.some(n) : O.none) + U.deepStrictEqual(TWI.traverseWithIndex(O.Applicative)({ b: 2 }, f), O.some({ b: 2 })) + U.deepStrictEqual(TWI.traverseWithIndex(O.Applicative)({ a: 1, b: 2 }, f), O.none) + // should respect the order + U.deepStrictEqual( + pipe(TWI.traverseWithIndex(O.Applicative)({ b: 2, c: 1 }, f), O.map(Object.keys)), + O.some(['c', 'b']) + ) + }) + it('wither', async () => { - const wither = _.wither(T.ApplicativePar)((n: number) => T.of(p(n) ? O.some(n + 1) : O.none)) + const f = (n: number) => T.of(p(n) ? O.some(n + 1) : O.none) + const wither = _.wither(T.ApplicativePar)(f) U.deepStrictEqual(await pipe({}, wither)(), {}) U.deepStrictEqual(await pipe({ a: 1, b: 3 }, wither)(), { b: 4 }) + + U.deepStrictEqual(await _.getWitherable(S.Ord).wither(T.ApplicativePar)({ a: 1, b: 3 }, f)(), { b: 4 }) }) it('wilt', async () => { @@ -386,10 +501,16 @@ describe('ReadonlyRecord', () => { }) it('getShow', () => { - const Sh = _.getShow(S.Show) + const Sh = _.getShow(S.Ord)(S.Show) U.deepStrictEqual(Sh.show({}), `{}`) U.deepStrictEqual(Sh.show({ a: 'a' }), `{ "a": "a" }`) U.deepStrictEqual(Sh.show({ a: 'a', b: 'b' }), `{ "a": "a", "b": "b" }`) + + // tslint:disable-next-line: deprecation + const DepSh = _.getShow(S.Show) + U.deepStrictEqual(DepSh.show({}), `{}`) + U.deepStrictEqual(DepSh.show({ a: 'a' }), `{ "a": "a" }`) + U.deepStrictEqual(DepSh.show({ a: 'a', b: 'b' }), `{ "a": "a", "b": "b" }`) }) it('singleton', () => { @@ -454,6 +575,74 @@ describe('ReadonlyRecord', () => { assert.notStrictEqual(bs, as) }) + it('getUnionMonoid', () => { + const M = _.getUnionMonoid(S.Semigroup) + const x: _.ReadonlyRecord = { + a: 'a1', + b: 'b1', + c: 'c1' + } + const y: _.ReadonlyRecord = { + b: 'b2', + c: 'c2', + d: 'd2' + } + U.strictEqual(M.concat(x, M.empty), x) + U.strictEqual(M.concat(M.empty, x), x) + U.strictEqual(M.concat(x, {}), x) + U.strictEqual(M.concat({}, x), x) + U.deepStrictEqual(M.concat(x, y), { + a: 'a1', + b: 'b1b2', + c: 'c1c2', + d: 'd2' + }) + }) + + it('getIntersectionSemigroup', () => { + const M = _.getIntersectionSemigroup(S.Semigroup) + const x: _.ReadonlyRecord = { + a: 'a1', + b: 'b1', + c: 'c1' + } + const y: _.ReadonlyRecord = { + b: 'b2', + c: 'c2', + d: 'd2' + } + U.strictEqual(M.concat(x, _.empty), _.empty) + U.strictEqual(M.concat(x, _.empty), _.empty) + U.strictEqual(M.concat(x, {}), _.empty) + U.strictEqual(M.concat(x, {}), _.empty) + U.deepStrictEqual(M.concat(x, y), { + b: 'b1b2', + c: 'c1c2' + }) + }) + + it('getDifferenceMagma', () => { + const M = _.getDifferenceMagma() + const x: _.ReadonlyRecord = { + a: 'a1', + b: 'b1', + c: 'c1' + } + const y: _.ReadonlyRecord = { + b: 'b2', + c: 'c2', + d: 'd2' + } + U.strictEqual(M.concat(_.empty, x), x) + U.strictEqual(M.concat(x, _.empty), x) + U.strictEqual(M.concat({}, x), x) + U.strictEqual(M.concat(x, {}), x) + U.deepStrictEqual(M.concat(x, y), { + a: 'a1', + d: 'd2' + }) + }) + it('mapWithIndex', () => { // should ignore non own properties const o: _.ReadonlyRecord = Object.create({ a: 1 }) diff --git a/test/ReadonlySet.ts b/test/ReadonlySet.ts index c531ae9ae..33e2bf434 100644 --- a/test/ReadonlySet.ts +++ b/test/ReadonlySet.ts @@ -140,6 +140,11 @@ describe('ReadonlySet', () => { U.deepStrictEqual(IS.concat(_.empty, new Set([1, 3])), _.empty) }) + it('getDifferenceMagma', () => { + const M = _.getDifferenceMagma(N.Eq) + U.deepStrictEqual(M.concat(new Set([1, 2]), new Set([1, 3])), new Set([2])) + }) + it('difference', () => { U.deepStrictEqual(_.difference(N.Eq)(new Set([1, 2]), new Set([1, 3])), new Set([2])) @@ -156,6 +161,12 @@ describe('ReadonlySet', () => { U.deepStrictEqual(_.foldMap(N.Ord, getMonoid())((a) => [a])(new Set([3, 2, 1])), [1, 2, 3]) }) + it('reduceRight', () => { + const f = _.reduceRight(N.Ord)('', (a, b) => b + a) + U.deepStrictEqual(f(new Set([1, 2, 3])), '321') + U.deepStrictEqual(f(new Set([3, 2, 1])), '321') + }) + it('singleton', () => { U.deepStrictEqual(_.singleton(1), new Set([1])) }) diff --git a/test/Record.ts b/test/Record.ts index 6e9da06df..100300190 100644 --- a/test/Record.ts +++ b/test/Record.ts @@ -5,6 +5,7 @@ import { identity, pipe } from '../src/function' import * as IO from '../src/IO' import * as N from '../src/number' import * as O from '../src/Option' +import { reverse } from '../src/Ord' import * as _ from '../src/Record' import * as Se from '../src/Semigroup' import { separated } from '../src/Separated' @@ -18,6 +19,19 @@ const noPrototype = Object.create(null) describe('Record', () => { describe('pipeables', () => { + it('collect', () => { + const x: { readonly a: string; readonly b: boolean } = { a: 'c', b: false } + U.deepStrictEqual(_.collect(S.Ord)((key, val) => ({ key: key, value: val }))(x), [ + { key: 'a', value: 'c' }, + { key: 'b', value: false } + ]) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(_.collect((key, val) => ({ key: key, value: val }))(x), [ + { key: 'a', value: 'c' }, + { key: 'b', value: false } + ]) + }) + it('map', () => { U.deepStrictEqual(pipe({ k1: 1, k2: 2 }, _.map(U.double)), { k1: 2, k2: 4 }) U.deepStrictEqual(pipe({ a: 1, b: 2 }, _.map(U.double)), { a: 2, b: 4 }) @@ -32,6 +46,22 @@ describe('Record', () => { U.deepStrictEqual( pipe( { k1: 'a', k2: 'b' }, + _.reduce(S.Ord)('', (b, a) => b + a) + ), + 'ab' + ) + U.deepStrictEqual( + pipe( + { k2: 'b', k1: 'a' }, + _.reduce(S.Ord)('', (b, a) => b + a) + ), + 'ab' + ) + + U.deepStrictEqual( + pipe( + { k1: 'a', k2: 'b' }, + // tslint:disable-next-line: deprecation _.reduce('', (b, a) => b + a) ), 'ab' @@ -39,6 +69,7 @@ describe('Record', () => { U.deepStrictEqual( pipe( { k2: 'b', k1: 'a' }, + // tslint:disable-next-line: deprecation _.reduce('', (b, a) => b + a) ), 'ab' @@ -46,11 +77,20 @@ describe('Record', () => { }) it('foldMap', () => { + U.deepStrictEqual(pipe({ a: 'a', b: 'b' }, _.foldMap(S.Ord)(S.Monoid)(identity)), 'ab') + U.deepStrictEqual(_.getFoldable(S.Ord).foldMap(S.Monoid)({ a: 'a', b: 'b' }, identity), 'ab') + + // tslint:disable-next-line: deprecation U.deepStrictEqual(pipe({ a: 'a', b: 'b' }, _.foldMap(S.Monoid)(identity)), 'ab') + // tslint:disable-next-line: deprecation + U.deepStrictEqual(_.Foldable.foldMap(S.Monoid)({ a: 'a', b: 'b' }, identity), 'ab') }) it('reduceRight', () => { const f = (a: string, acc: string) => acc + a + U.deepStrictEqual(pipe({ a: 'a', b: 'b' }, _.reduceRight(S.Ord)('', f)), 'ba') + + // tslint:disable-next-line: deprecation U.deepStrictEqual(pipe({ a: 'a', b: 'b' }, _.reduceRight('', f)), 'ba') }) @@ -105,6 +145,22 @@ describe('Record', () => { U.deepStrictEqual( pipe( { k1: 'a', k2: 'b' }, + _.reduceWithIndex(S.Ord)('', (k, b, a) => b + k + a) + ), + 'k1ak2b' + ) + U.deepStrictEqual( + pipe( + { k2: 'b', k1: 'a' }, + _.reduceWithIndex(S.Ord)('', (k, b, a) => b + k + a) + ), + 'k1ak2b' + ) + + U.deepStrictEqual( + pipe( + { k1: 'a', k2: 'b' }, + // tslint:disable-next-line: deprecation _.reduceWithIndex('', (k, b, a) => b + k + a) ), 'k1ak2b' @@ -112,6 +168,7 @@ describe('Record', () => { U.deepStrictEqual( pipe( { k2: 'b', k1: 'a' }, + // tslint:disable-next-line: deprecation _.reduceWithIndex('', (k, b, a) => b + k + a) ), 'k1ak2b' @@ -122,16 +179,42 @@ describe('Record', () => { U.deepStrictEqual( pipe( { k1: 'a', k2: 'b' }, + _.foldMapWithIndex(S.Ord)(S.Monoid)((k, a) => k + a) + ), + 'k1ak2b' + ) + U.deepStrictEqual( + _.getFoldableWithIndex(S.Ord).foldMapWithIndex(S.Monoid)({ k1: 'a', k2: 'b' }, (k, a) => k + a), + 'k1ak2b' + ) + + U.deepStrictEqual( + pipe( + { k1: 'a', k2: 'b' }, + // tslint:disable-next-line: deprecation _.foldMapWithIndex(S.Monoid)((k, a) => k + a) ), 'k1ak2b' ) + U.deepStrictEqual( + // tslint:disable-next-line: deprecation + _.FoldableWithIndex.foldMapWithIndex(S.Monoid)({ k1: 'a', k2: 'b' }, (k, a) => k + a), + 'k1ak2b' + ) }) it('reduceRightWithIndex', () => { U.deepStrictEqual( pipe( { k1: 'a', k2: 'b' }, + _.reduceRightWithIndex(S.Ord)('', (k, a, b) => b + k + a) + ), + 'k2bk1a' + ) + U.deepStrictEqual( + pipe( + { k1: 'a', k2: 'b' }, + // tslint:disable-next-line: deprecation _.reduceRightWithIndex('', (k, a, b) => b + k + a) ), 'k2bk1a' @@ -184,14 +267,18 @@ describe('Record', () => { O.some({ a: 1, b: 2 }) ) U.deepStrictEqual(_.traverse(O.Applicative)((n: number) => (n >= 2 ? O.some(n) : O.none))({ a: 1, b: 2 }), O.none) + }) + it('getTraversable', () => { + const T = _.getTraversable(reverse(S.Ord)) + const f = (n: number) => (n <= 2 ? O.some(n) : O.none) + U.deepStrictEqual(T.traverse(O.Applicative)({ a: 1, b: 2 }, f), O.some({ a: 1, b: 2 })) + U.deepStrictEqual(T.traverse(O.Applicative)({ a: 1, b: 3 }, f), O.none) + // should respect the order + U.deepStrictEqual(pipe(T.traverse(O.Applicative)({ b: 2, a: 1 }, f), O.map(Object.keys)), O.some(['b', 'a'])) U.deepStrictEqual( - _.Traversable.traverse(O.Applicative)({ a: 1, b: 2 }, (n: number) => (n <= 2 ? O.some(n) : O.none)), - O.some({ a: 1, b: 2 }) - ) - U.deepStrictEqual( - _.Traversable.traverse(O.Applicative)({ a: 1, b: 2 }, (n: number) => (n >= 2 ? O.some(n) : O.none)), - O.none + pipe(T.sequence(O.Applicative)({ b: O.some(2), a: O.some(1) }), O.map(Object.keys)), + O.some(['b', 'a']) ) }) @@ -199,20 +286,42 @@ describe('Record', () => { const sequence = _.sequence(O.Applicative) U.deepStrictEqual(sequence({ a: O.some(1), b: O.some(2) }), O.some({ a: 1, b: 2 })) U.deepStrictEqual(sequence({ a: O.none, b: O.some(2) }), O.none) + + U.deepStrictEqual( + // tslint:disable-next-line: deprecation + _.record.sequence(O.Applicative)({ a: O.some(1), b: O.some(2) }), + O.some({ a: 1, b: 2 }) + ) }) it('traverseWithIndex', () => { - const traverseWithIndex = _.traverseWithIndex(O.Applicative)( - (k, n: number): O.Option => (k !== 'a' ? O.some(n) : O.none) - ) + const f = (k: string, n: number): O.Option => (k !== 'a' ? O.some(n) : O.none) + const traverseWithIndex = _.traverseWithIndex(O.Applicative)(f) U.deepStrictEqual(pipe({ a: 1, b: 2 }, traverseWithIndex), O.none) U.deepStrictEqual(pipe({ b: 2 }, traverseWithIndex), O.some({ b: 2 })) + U.deepStrictEqual(pipe({}, traverseWithIndex), O.some({})) + }) + + it('getTraversableWithIndex', () => { + const TWI = _.getTraversableWithIndex(reverse(S.Ord)) + const f = (k: string, n: number): O.Option => (k !== 'a' ? O.some(n) : O.none) + U.deepStrictEqual(TWI.traverseWithIndex(O.Applicative)({ b: 2 }, f), O.some({ b: 2 })) + U.deepStrictEqual(TWI.traverseWithIndex(O.Applicative)({ a: 1, b: 2 }, f), O.none) + U.deepStrictEqual(TWI.traverseWithIndex(O.Applicative)({}, f), O.some({})) + // should respect the order + U.deepStrictEqual( + pipe(TWI.traverseWithIndex(O.Applicative)({ b: 2, c: 1 }, f), O.map(Object.keys)), + O.some(['c', 'b']) + ) }) it('wither', async () => { - const wither = _.wither(T.ApplicativePar)((n: number) => T.of(p(n) ? O.some(n + 1) : O.none)) + const f = (n: number) => T.of(p(n) ? O.some(n + 1) : O.none) + const wither = _.wither(T.ApplicativePar)(f) U.deepStrictEqual(await pipe({}, wither)(), {}) U.deepStrictEqual(await pipe({ a: 1, b: 3 }, wither)(), { b: 4 }) + + U.deepStrictEqual(await _.getWitherable(S.Ord).wither(T.ApplicativePar)({ a: 1, b: 3 }, f)(), { b: 4 }) }) it('wilt', async () => { @@ -382,10 +491,16 @@ describe('Record', () => { }) it('getShow', () => { - const Sh = _.getShow(S.Show) + const Sh = _.getShow(S.Ord)(S.Show) U.deepStrictEqual(Sh.show({}), `{}`) U.deepStrictEqual(Sh.show({ a: 'a' }), `{ "a": "a" }`) U.deepStrictEqual(Sh.show({ a: 'a', b: 'b' }), `{ "a": "a", "b": "b" }`) + + // tslint:disable-next-line: deprecation + const DepSh = _.getShow(S.Show) + U.deepStrictEqual(DepSh.show({}), `{}`) + U.deepStrictEqual(DepSh.show({ a: 'a' }), `{ "a": "a" }`) + U.deepStrictEqual(DepSh.show({ a: 'a', b: 'b' }), `{ "a": "a", "b": "b" }`) }) it('singleton', () => { @@ -425,4 +540,72 @@ describe('Record', () => { O.some(false) ) }) + + it('getUnionMonoid', () => { + const M = _.getUnionMonoid(S.Semigroup) + const x: Record = { + a: 'a1', + b: 'b1', + c: 'c1' + } + const y: Record = { + b: 'b2', + c: 'c2', + d: 'd2' + } + U.deepStrictEqual(M.concat(x, M.empty), x) + U.deepStrictEqual(M.concat(M.empty, x), x) + U.deepStrictEqual(M.concat(x, {}), x) + U.deepStrictEqual(M.concat({}, x), x) + U.deepStrictEqual(M.concat(x, y), { + a: 'a1', + b: 'b1b2', + c: 'c1c2', + d: 'd2' + }) + }) + + it('getIntersectionSemigroup', () => { + const M = _.getIntersectionSemigroup(S.Semigroup) + const x: Record = { + a: 'a1', + b: 'b1', + c: 'c1' + } + const y: Record = { + b: 'b2', + c: 'c2', + d: 'd2' + } + U.deepStrictEqual(M.concat(x, {}), {}) + U.deepStrictEqual(M.concat(x, {}), {}) + U.deepStrictEqual(M.concat(x, {}), {}) + U.deepStrictEqual(M.concat(x, {}), {}) + U.deepStrictEqual(M.concat(x, y), { + b: 'b1b2', + c: 'c1c2' + }) + }) + + it('getDifferenceMagma', () => { + const M = _.getDifferenceMagma() + const x: Record = { + a: 'a1', + b: 'b1', + c: 'c1' + } + const y: Record = { + b: 'b2', + c: 'c2', + d: 'd2' + } + U.deepStrictEqual(M.concat({}, x), x) + U.deepStrictEqual(M.concat(x, {}), x) + U.deepStrictEqual(M.concat({}, x), x) + U.deepStrictEqual(M.concat(x, {}), x) + U.deepStrictEqual(M.concat(x, y), { + a: 'a1', + d: 'd2' + }) + }) }) diff --git a/test/Refinement.ts b/test/Refinement.ts new file mode 100644 index 000000000..7640ee271 --- /dev/null +++ b/test/Refinement.ts @@ -0,0 +1,90 @@ +import * as B from '../src/boolean' +import * as E from '../src/Either' +import { pipe } from '../src/function' +import * as N from '../src/number' +import * as O from '../src/Option' +import { ReadonlyRecord } from '../src/ReadonlyRecord' +import * as _ from '../src/Refinement' +import * as S from '../src/string' +import * as U from './util' + +interface NonEmptyStringBrand { + readonly NonEmptyString: unique symbol +} + +type NonEmptyString = string & NonEmptyStringBrand + +const NonEmptyString: _.Refinement = (s): s is NonEmptyString => s.length > 0 + +describe('Refinement', () => { + it('not', () => { + const r1: _.Refinement = S.isString + const r2 = _.not(r1) + U.deepStrictEqual(r2('a'), false) + U.deepStrictEqual(r2(1), true) + }) + + it('or', () => { + const r = pipe(S.isString, _.or(N.isNumber), _.or(B.isBoolean)) + U.deepStrictEqual(r({}), false) + U.deepStrictEqual(r('a'), true) + U.deepStrictEqual(r(1), true) + U.deepStrictEqual(r(true), true) + }) + + it('and', () => { + const ra = (r: ReadonlyRecord): r is { readonly a: string } => S.isString(r['a']) + const rb = (r: ReadonlyRecord): r is { readonly b: number } => N.isNumber(r['b']) + const r = pipe(ra, _.and(rb)) + U.deepStrictEqual(r({ a: 'a' }), false) + U.deepStrictEqual(r({ b: 1 }), false) + U.deepStrictEqual(r({}), false) + U.deepStrictEqual(r({ a: 'a', b: 'b' }), false) + U.deepStrictEqual(r({ a: 1, b: 2 }), false) + U.deepStrictEqual(r({ a: 'a', b: 1 }), true) + }) + + it('fromOptionK', () => { + const f = (s: string | number): O.Option => (typeof s === 'string' ? O.some(s) : O.none) + const isString = _.fromOptionK(f) + U.deepStrictEqual(isString('s'), true) + U.deepStrictEqual(isString(1), false) + type A = { readonly type: 'A' } + type B = { readonly type: 'B' } + type C = A | B + const isA = _.fromOptionK((c) => (c.type === 'A' ? O.some(c) : O.none)) + U.deepStrictEqual(isA({ type: 'A' }), true) + U.deepStrictEqual(isA({ type: 'B' }), false) + }) + + it('zero', () => { + const refinement = _.zero() + U.strictEqual(refinement('a'), false) + }) + + it('id', () => { + const refinement = _.id() + U.strictEqual(refinement('a'), true) + }) + + it('compose', () => { + const refinement = pipe(S.isString, _.compose(NonEmptyString)) + U.strictEqual(refinement('a'), true) + U.strictEqual(refinement(null), false) + U.strictEqual(refinement(''), false) + }) + + it('fromEitherK', () => { + const f = (s: string | number): E.Either => + typeof s === 'string' ? E.right(s) : E.left('not a string') + const isString = _.fromEitherK(f) + U.deepStrictEqual(isString('s'), true) + U.deepStrictEqual(isString(1), false) + type A = { readonly type: 'A' } + type B = { readonly type: 'B' } + type C = A | B + const isA = _.fromEitherK((c) => (c.type === 'A' ? E.right(c) : E.left('not as A'))) + U.deepStrictEqual(isA({ type: 'A' }), true) + U.deepStrictEqual(isA({ type: 'B' }), false) + }) +}) diff --git a/test/Semigroup.ts b/test/Semigroup.ts index d37ecc7ad..22cf88e8f 100644 --- a/test/Semigroup.ts +++ b/test/Semigroup.ts @@ -36,6 +36,7 @@ describe('Semigroup', () => { }) it('semigroupVoid', () => { + // tslint:disable-next-line: deprecation U.deepStrictEqual(_.semigroupVoid.concat(undefined, undefined), undefined) }) @@ -55,4 +56,49 @@ describe('Semigroup', () => { const S = _.struct(Object.create({ a: 1 })) U.deepStrictEqual(S.concat({}, {}), {}) }) + + it('semigroupAll', () => { + // tslint:disable-next-line: deprecation + const S = _.semigroupAll + U.deepStrictEqual(S.concat(true, true), true) + U.deepStrictEqual(S.concat(false, true), false) + U.deepStrictEqual(S.concat(true, false), false) + U.deepStrictEqual(S.concat(false, false), false) + }) + + it('semigroupAny', () => { + // tslint:disable-next-line: deprecation + const S = _.semigroupAny + U.deepStrictEqual(S.concat(true, true), true) + U.deepStrictEqual(S.concat(false, true), true) + U.deepStrictEqual(S.concat(true, false), true) + U.deepStrictEqual(S.concat(false, false), false) + }) + + it('semigroupSum', () => { + // tslint:disable-next-line: deprecation + U.deepStrictEqual(_.semigroupSum.concat(2, 3), 5) + }) + + it('semigroupProduct', () => { + // tslint:disable-next-line: deprecation + U.deepStrictEqual(_.semigroupProduct.concat(2, 3), 6) + }) + + it('getObjectSemigroup', () => { + type T = { + readonly foo?: number + readonly bar: string + } + const foo: T = { + foo: 123, + bar: '456' + } + const bar: T = { + bar: '123' + } + // tslint:disable-next-line: deprecation + const S = _.getObjectSemigroup() + U.deepStrictEqual(S.concat(foo, bar), Object.assign({}, foo, bar)) + }) }) diff --git a/test/Set.ts b/test/Set.ts index 0ea49ec9a..5cf34122e 100644 --- a/test/Set.ts +++ b/test/Set.ts @@ -136,6 +136,11 @@ describe('Set', () => { U.deepStrictEqual(IS.concat(_.empty, new Set([1, 3])), _.empty) }) + it('getDifferenceMagma', () => { + const M = _.getDifferenceMagma(N.Eq) + U.deepStrictEqual(M.concat(new Set([1, 2]), new Set([1, 3])), new Set([2])) + }) + it('difference', () => { U.deepStrictEqual(_.difference(N.Eq)(new Set([1, 2]), new Set([1, 3])), new Set([2])) diff --git a/test/Show.ts b/test/Show.ts index b3a799647..ea9c86b50 100644 --- a/test/Show.ts +++ b/test/Show.ts @@ -17,4 +17,21 @@ describe('Show', () => { const Sh = _.tuple(S.Show, N.Show) U.deepStrictEqual(Sh.show(['a', 1]), '["a", 1]') }) + + it('showBoolean', () => { + // tslint:disable-next-line: deprecation + const Sh = _.showBoolean + U.deepStrictEqual(Sh.show(true), 'true') + U.deepStrictEqual(Sh.show(false), 'false') + }) + + it('showNumber', () => { + // tslint:disable-next-line: deprecation + U.deepStrictEqual(_.showNumber.show(1), '1') + }) + + it('showString', () => { + // tslint:disable-next-line: deprecation + U.deepStrictEqual(_.showString.show('a'), '"a"') + }) }) diff --git a/test/State.ts b/test/State.ts index 4d10543f2..0cb3153b7 100644 --- a/test/State.ts +++ b/test/State.ts @@ -1,6 +1,8 @@ -import * as U from './util' import { pipe, tuple } from '../src/function' +import * as RA from '../src/ReadonlyArray' +import { ReadonlyNonEmptyArray } from '../src/ReadonlyNonEmptyArray' import * as _ from '../src/State' +import * as U from './util' describe('State', () => { describe('pipeables', () => { @@ -87,11 +89,23 @@ describe('State', () => { U.deepStrictEqual(pipe(_.of(1), _.bindTo('a'), _.apS('b', _.of('b')))(undefined), [{ a: 1, b: 'b' }, undefined]) }) - it('sequenceArray', () => { - const append = (n: number): _.State, number> => (s) => [n, [...s, n]] - U.deepStrictEqual(pipe([append(1), append(2)], _.sequenceArray)([]), [ - [1, 2], - [1, 2] - ]) + describe('array utils', () => { + const input: ReadonlyNonEmptyArray = ['a', 'b'] + + it('traverseReadonlyArrayWithIndex', () => { + const f = _.traverseReadonlyArrayWithIndex((i, a: string) => _.of(a + i)) + U.deepStrictEqual(pipe(RA.empty, f)({}), [RA.empty, {}]) + U.deepStrictEqual(pipe(input, f)({}), [['a0', 'b1'], {}]) + }) + + // old + it('sequenceArray', () => { + const append = (n: number): _.State, number> => (s) => [n, [...s, n]] + // tslint:disable-next-line: deprecation + U.deepStrictEqual(pipe([append(1), append(2)], _.sequenceArray)([]), [ + [1, 2], + [1, 2] + ]) + }) }) }) diff --git a/test/StateReaderTaskEither.ts b/test/StateReaderTaskEither.ts index 03797904a..7a5517f1a 100644 --- a/test/StateReaderTaskEither.ts +++ b/test/StateReaderTaskEither.ts @@ -1,13 +1,15 @@ import * as assert from 'assert' import * as A from '../src/Array' import * as E from '../src/Either' -import { pipe, tuple } from '../src/function' +import { pipe, SK, tuple } from '../src/function' import * as I from '../src/IO' import * as IE from '../src/IOEither' import * as O from '../src/Option' import * as R from '../src/Reader' import * as RE from '../src/ReaderEither' import * as RTE from '../src/ReaderTaskEither' +import * as RA from '../src/ReadonlyArray' +import { ReadonlyNonEmptyArray } from '../src/ReadonlyNonEmptyArray' import { State } from '../src/State' import * as _ from '../src/StateReaderTaskEither' import * as S from '../src/string' @@ -76,11 +78,26 @@ describe('StateReaderTaskEither', () => { U.deepStrictEqual(e, E.right('aaa')) }) - it('chainFirst', async () => { + it('flatten', async () => { const e = await pipe(_.right(_.right('a')), _.flatten, _.evaluate(state))({})() U.deepStrictEqual(e, E.right('a')) }) + type S = unknown + type R1 = { readonly env1: unknown } + type R2 = { readonly env2: unknown } + type E1 = { readonly left1: unknown } + type E2 = { readonly left2: unknown } + + it('flattenW', async () => { + const e = await pipe( + _.right>(_.right('a')), + _.flattenW, + _.evaluate(state) + )({ env1: '', env2: '' })() + U.deepStrictEqual(e, E.right('a')) + }) + it('bimap', async () => { const gt2 = (n: number): boolean => n > 2 const e1 = await pipe(_.right('aaa'), _.bimap(gt2, S.size), _.evaluate(state))({})() @@ -328,26 +345,92 @@ describe('StateReaderTaskEither', () => { ) }) - it('sequenceArray', async () => { - // tslint:disable-next-line: readonly-array - const log: Array = [] - const right = (n: number): _.StateReaderTaskEither => - _.rightIO(() => { - log.push(n) - return n - }) - const left = (s: string): _.StateReaderTaskEither => - _.leftIO(() => { - log.push(s) - return s - }) - assert.deepStrictEqual( - await pipe([right(1), right(2)], _.sequenceArray)(undefined)(undefined)(), - E.right([[1, 2], undefined]) - ) - U.deepStrictEqual(await pipe([right(3), left('a')], _.sequenceArray)(undefined)(undefined)(), E.left('a')) - U.deepStrictEqual(await pipe([left('b'), right(4)], _.sequenceArray)(undefined)(undefined)(), E.left('b')) - U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + describe('array utils', () => { + const input: ReadonlyNonEmptyArray = ['a', 'b'] + + it('traverseReadonlyArrayWithIndex', async () => { + const f = _.traverseReadonlyArrayWithIndex((i, a: string) => (a.length > 0 ? _.right(a + i) : _.left('e'))) + U.deepStrictEqual(await pipe(RA.empty, f)(undefined)(undefined)(), E.right(tuple(RA.empty, undefined))) + U.deepStrictEqual(await pipe(input, f)(undefined)(undefined)(), E.right(tuple(['a0', 'b1'], undefined))) + U.deepStrictEqual(await pipe(['a', ''], f)(undefined)(undefined)(), E.left('e')) + const append = (_i: number, n: number): _.StateReaderTaskEither, {}, Error, void> => + _.modify((a) => [...a, n]) + U.deepStrictEqual( + await pipe( + [1, 2, 3], + _.traverseReadonlyArrayWithIndex(append), + _.map(() => undefined) + )([])({})(), + E.right(tuple(undefined, [1, 2, 3])) + ) + }) + + it('sequenceReadonlyArray', async () => { + const log: Array = [] + const right = (n: number): _.StateReaderTaskEither => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.StateReaderTaskEither => + _.leftIO(() => { + log.push(s) + return s + }) + U.deepStrictEqual( + await pipe([right(1), right(2)], _.traverseReadonlyArrayWithIndex(SK))(undefined)(undefined)(), + E.right(tuple([1, 2], undefined)) + ) + U.deepStrictEqual( + await pipe([right(3), left('a')], _.traverseReadonlyArrayWithIndex(SK))(undefined)(undefined)(), + E.left('a') + ) + U.deepStrictEqual( + await pipe([left('b'), right(4)], _.traverseReadonlyArrayWithIndex(SK))(undefined)(undefined)(), + E.left('b') + ) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + }) + + // old + it('sequenceArray', async () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const right = (n: number): _.StateReaderTaskEither => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.StateReaderTaskEither => + _.leftIO(() => { + log.push(s) + return s + }) + assert.deepStrictEqual( + // tslint:disable-next-line: deprecation + await pipe([right(1), right(2)], _.sequenceArray)(undefined)(undefined)(), + E.right([[1, 2], undefined]) + ) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([right(3), left('a')], _.sequenceArray)(undefined)(undefined)(), E.left('a')) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([left('b'), right(4)], _.sequenceArray)(undefined)(undefined)(), E.left('b')) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + }) + + it('#1486', async () => { + const append = (n: number): _.StateReaderTaskEither, {}, Error, void> => + _.modify((a) => [...a, n]) + U.deepStrictEqual( + await pipe( + [1, 2, 3], + // tslint:disable-next-line: deprecation + _.traverseArray(append), + _.map(() => undefined) + )([])({})(), + E.right(tuple(undefined, [1, 2, 3])) + ) + }) }) it('fromState', async () => { @@ -356,16 +439,35 @@ describe('StateReaderTaskEither', () => { U.deepStrictEqual(e, E.right(1)) }) - it('#1486', async () => { - const append = (n: number): _.StateReaderTaskEither, {}, Error, void> => - _.modify((a) => [...a, n]) + it('fromStateK', async () => { + const ma = _.fromStateK((n: number): State => (s) => [n * 2, s + 1]) + U.deepStrictEqual(await ma(3)(2)({})(), E.right([6, 3])) + }) + + it('chainStateK', async () => { + const f = _.chainStateK((n: number): State => (s) => [n * 2, s + 1]) + const right: _.StateReaderTaskEither = _.right(3) + U.deepStrictEqual(await pipe(right, f)(2)({})(), E.right([6, 3])) + const left: _.StateReaderTaskEither = _.left('a') + U.deepStrictEqual(await pipe(left, f)(2)({})(), E.left('a')) + }) + + it('local', async () => { U.deepStrictEqual( await pipe( - [1, 2, 3], - _.traverseArray(append), - _.map(() => undefined) - )([])({})(), - E.right(tuple(undefined, [1, 2, 3])) + _.asks((n: number) => n + 1), + _.local(S.size) + )({})('aaa')(), + E.right(tuple(4, {})) ) }) + + it('asksStateReaderTaskEither', async () => { + interface Env { + readonly count: number + } + const e: Env = { count: 0 } + const f = (e: Env) => _.of(e.count + 1) + U.deepStrictEqual(await _.asksStateReaderTaskEither(f)({})(e)(), E.right(tuple(1, {}))) + }) }) diff --git a/test/Task.ts b/test/Task.ts index 83be2bf09..174b7b649 100644 --- a/test/Task.ts +++ b/test/Task.ts @@ -1,10 +1,11 @@ import * as U from './util' -import { pipe } from '../src/function' +import { pipe, SK } from '../src/function' import * as I from '../src/IO' import * as RA from '../src/ReadonlyArray' import * as _ from '../src/Task' import * as assert from 'assert' import * as S from '../src/string' +import { ReadonlyNonEmptyArray } from '../src/ReadonlyNonEmptyArray' const delayReject = (n: number, a: A): _.Task => () => new Promise((_, reject) => { @@ -163,33 +164,80 @@ describe('Task', () => { U.deepStrictEqual(await pipe(_.of(1), _.bindTo('a'), _.apS('b', _.of('b')))(), { a: 1, b: 'b' }) }) - it('sequenceArray', async () => { - // tslint:disable-next-line: readonly-array - const log: Array = [] - const append = (n: number): _.Task => - _.delay(n % 2 === 0 ? 50 : 100)( - _.fromIO(() => { - log.push(n) - return n - }) - ) - const as = RA.makeBy(4, append) - U.deepStrictEqual(await pipe(as, _.sequenceArray)(), [0, 1, 2, 3]) - U.deepStrictEqual(log, [0, 2, 1, 3]) - }) - - it('sequenceSeqArray', async () => { - // tslint:disable-next-line: readonly-array - const log: Array = [] - const append = (n: number): _.Task => - _.delay(n % 2 === 0 ? 50 : 100)( - _.fromIO(() => { - log.push(n) - return n - }) - ) - const as = RA.makeBy(4, append) - U.deepStrictEqual(await pipe(as, _.sequenceSeqArray)(), [0, 1, 2, 3]) - U.deepStrictEqual(log, [0, 1, 2, 3]) + describe('array utils', () => { + const input: ReadonlyNonEmptyArray = ['a', 'b'] + + it('traverseReadonlyArrayWithIndex', async () => { + const f = _.traverseReadonlyArrayWithIndex((i, a: string) => _.of(a + i)) + U.deepStrictEqual(await pipe(RA.empty, f)(), RA.empty) + U.deepStrictEqual(await pipe(input, f)(), ['a0', 'b1']) + }) + + it('traverseReadonlyArrayWithIndexSeq', async () => { + const f = _.traverseReadonlyArrayWithIndexSeq((i, a: string) => _.of(a + i)) + U.deepStrictEqual(await pipe(RA.empty, f)(), RA.empty) + U.deepStrictEqual(await pipe(input, f)(), ['a0', 'b1']) + }) + + it('sequenceReadonlyArray', async () => { + const log: Array = [] + const append = (n: number): _.Task => + _.delay(n % 2 === 0 ? 50 : 100)( + _.fromIO(() => { + log.push(n) + return n + }) + ) + const as = RA.makeBy(4, append) + U.deepStrictEqual(await pipe(as, _.traverseReadonlyArrayWithIndex(SK))(), [0, 1, 2, 3]) + U.deepStrictEqual(log, [0, 2, 1, 3]) + }) + + it('sequenceReadonlyArraySeq', async () => { + const log: Array = [] + const append = (n: number): _.Task => + _.delay(n % 2 === 0 ? 50 : 100)( + _.fromIO(() => { + log.push(n) + return n + }) + ) + const as = RA.makeBy(4, append) + U.deepStrictEqual(await pipe(as, _.traverseReadonlyArrayWithIndexSeq(SK))(), [0, 1, 2, 3]) + U.deepStrictEqual(log, [0, 1, 2, 3]) + }) + + // old + it('sequenceArray', async () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const append = (n: number): _.Task => + _.delay(n % 2 === 0 ? 50 : 100)( + _.fromIO(() => { + log.push(n) + return n + }) + ) + const as = RA.makeBy(4, append) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe(as, _.sequenceArray)(), [0, 1, 2, 3]) + U.deepStrictEqual(log, [0, 2, 1, 3]) + }) + + it('sequenceSeqArray', async () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const append = (n: number): _.Task => + _.delay(n % 2 === 0 ? 50 : 100)( + _.fromIO(() => { + log.push(n) + return n + }) + ) + const as = RA.makeBy(4, append) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe(as, _.sequenceSeqArray)(), [0, 1, 2, 3]) + U.deepStrictEqual(log, [0, 1, 2, 3]) + }) }) }) diff --git a/test/TaskEither.ts b/test/TaskEither.ts index e8d736483..afb972281 100644 --- a/test/TaskEither.ts +++ b/test/TaskEither.ts @@ -2,7 +2,7 @@ import * as U from './util' import { sequenceT } from '../src/Apply' import * as RA from '../src/ReadonlyArray' import * as E from '../src/Either' -import { identity, pipe } from '../src/function' +import { identity, pipe, SK } from '../src/function' import * as I from '../src/IO' import * as IE from '../src/IOEither' import { monoidString } from '../src/Monoid' @@ -10,9 +10,11 @@ import { none, some } from '../src/Option' import { pipeable } from '../src/pipeable' import * as N from '../src/number' import * as T from '../src/Task' +import * as TO from '../src/TaskOption' import * as _ from '../src/TaskEither' import * as S from '../src/string' import { left, right } from '../src/Separated' +import { ReadonlyNonEmptyArray } from '../src/ReadonlyNonEmptyArray' describe('TaskEither', () => { // ------------------------------------------------------------------------------------- @@ -86,6 +88,13 @@ describe('TaskEither', () => { U.deepStrictEqual(await pipe(_.right(_.right('a')), _.flatten)(), E.right('a')) }) + it('flattenW', async () => { + U.deepStrictEqual( + await pipe(_.right<'left1', _.TaskEither<'left2', 'a'>>(_.right('a')), _.flattenW)(), + E.right('a') + ) + }) + it('bimap', async () => { const f = (s: string): number => s.length const g = (n: number): boolean => n > 2 @@ -391,6 +400,43 @@ describe('TaskEither', () => { ) }) + it('orElseW', async () => { + U.deepStrictEqual( + await pipe( + _.left('foo'), + _.orElseW((l) => _.right(l.length)) + )(), + E.right(3) + ) + U.deepStrictEqual( + await pipe( + _.right(1), + _.orElseW(() => _.right(2)) + )(), + E.right(1) + ) + }) + + it('orElseFirst', async () => { + const f = _.orElseFirst((e: string) => (e.length <= 1 ? _.right(true) : _.left(e + '!'))) + U.deepStrictEqual(await pipe(_.right(1), f)(), E.right(1)) + U.deepStrictEqual(await pipe(_.left('a'), f)(), E.left('a')) + U.deepStrictEqual(await pipe(_.left('aa'), f)(), E.left('aa!')) + }) + + it('orElseFirstW', async () => { + const f = _.orElseFirstW((e: string) => (e.length <= 1 ? _.right(true) : _.left(e + '!'))) + U.deepStrictEqual(await pipe(_.right(1), f)(), E.right(1)) + U.deepStrictEqual(await pipe(_.left('a'), f)(), E.left('a')) + U.deepStrictEqual(await pipe(_.left('aa'), f)(), E.left('aa!')) + }) + + it('orLeft', async () => { + const f = _.orLeft((e: string) => T.of(e + '!')) + U.deepStrictEqual(await pipe(_.right(1), f)(), E.right(1)) + U.deepStrictEqual(await pipe(_.left('a'), f)(), E.left('a!')) + }) + it('swap', async () => { U.deepStrictEqual(await _.swap(_.right(1))(), E.left(1)) U.deepStrictEqual(await _.swap(_.left('a'))(), E.right('a')) @@ -471,6 +517,23 @@ describe('TaskEither', () => { ) }) + it('fromTaskOption', async () => { + U.deepStrictEqual( + await pipe( + TO.none, + _.fromTaskOption(() => 'none') + )(), + E.left('none') + ) + U.deepStrictEqual( + await pipe( + TO.some(1), + _.fromTaskOption(() => 'none') + )(), + E.right(1) + ) + }) + it('fromPredicate', async () => { const gt2 = _.fromPredicate( (n: number) => n >= 2, @@ -501,42 +564,103 @@ describe('TaskEither', () => { ) }) - it('sequenceArray', async () => { - // tslint:disable-next-line: readonly-array - const log: Array = [] - const right = (n: number): _.TaskEither => - _.rightIO(() => { - log.push(n) - return n - }) - const left = (s: string): _.TaskEither => - _.leftIO(() => { - log.push(s) - return s - }) - U.deepStrictEqual(await pipe([right(1), right(2)], _.sequenceArray)(), E.right([1, 2])) - U.deepStrictEqual(await pipe([right(3), left('a')], _.sequenceArray)(), E.left('a')) - U.deepStrictEqual(await pipe([left('b'), right(4)], _.sequenceArray)(), E.left('b')) - U.deepStrictEqual(log, [1, 2, 3, 'a', 'b', 4]) - }) + describe('array utils', () => { + const input: ReadonlyNonEmptyArray = ['a', 'b'] - it('sequenceSeqArray', async () => { - // tslint:disable-next-line: readonly-array - const log: Array = [] - const right = (n: number): _.TaskEither => - _.rightIO(() => { - log.push(n) - return n - }) - const left = (s: string): _.TaskEither => - _.leftIO(() => { - log.push(s) - return s - }) - U.deepStrictEqual(await pipe([right(1), right(2)], _.sequenceSeqArray)(), E.right([1, 2])) - U.deepStrictEqual(await pipe([right(3), left('a')], _.sequenceSeqArray)(), E.left('a')) - U.deepStrictEqual(await pipe([left('b'), right(4)], _.sequenceSeqArray)(), E.left('b')) - U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + it('traverseReadonlyArrayWithIndex', async () => { + const f = _.traverseReadonlyArrayWithIndex((i, a: string) => (a.length > 0 ? _.right(a + i) : _.left('e'))) + U.deepStrictEqual(await pipe(RA.empty, f)(), E.right(RA.empty)) + U.deepStrictEqual(await pipe(input, f)(), E.right(['a0', 'b1'])) + U.deepStrictEqual(await pipe(['a', ''], f)(), E.left('e')) + }) + + it('traverseReadonlyArrayWithIndexSeq', async () => { + const f = _.traverseReadonlyArrayWithIndexSeq((i, a: string) => (a.length > 0 ? _.right(a + i) : _.left('e'))) + U.deepStrictEqual(await pipe(RA.empty, f)(), E.right(RA.empty)) + U.deepStrictEqual(await pipe(input, f)(), E.right(['a0', 'b1'])) + U.deepStrictEqual(await pipe(['a', ''], f)(), E.left('e')) + }) + + it('sequenceReadonlyArray', async () => { + const log: Array = [] + const right = (n: number): _.TaskEither => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.TaskEither => + _.leftIO(() => { + log.push(s) + return s + }) + U.deepStrictEqual(await pipe([right(1), right(2)], _.traverseReadonlyArrayWithIndex(SK))(), E.right([1, 2])) + U.deepStrictEqual(await pipe([right(3), left('a')], _.traverseReadonlyArrayWithIndex(SK))(), E.left('a')) + U.deepStrictEqual(await pipe([left('b'), right(4)], _.traverseReadonlyArrayWithIndex(SK))(), E.left('b')) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b', 4]) + }) + + it('sequenceReadonlyArraySeq', async () => { + const log: Array = [] + const right = (n: number): _.TaskEither => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.TaskEither => + _.leftIO(() => { + log.push(s) + return s + }) + U.deepStrictEqual(await pipe([right(1), right(2)], _.traverseReadonlyArrayWithIndexSeq(SK))(), E.right([1, 2])) + U.deepStrictEqual(await pipe([right(3), left('a')], _.traverseReadonlyArrayWithIndexSeq(SK))(), E.left('a')) + U.deepStrictEqual(await pipe([left('b'), right(4)], _.traverseReadonlyArrayWithIndexSeq(SK))(), E.left('b')) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + }) + + // old + it('sequenceArray', async () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const right = (n: number): _.TaskEither => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.TaskEither => + _.leftIO(() => { + log.push(s) + return s + }) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([right(1), right(2)], _.sequenceArray)(), E.right([1, 2])) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([right(3), left('a')], _.sequenceArray)(), E.left('a')) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([left('b'), right(4)], _.sequenceArray)(), E.left('b')) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b', 4]) + }) + + it('sequenceSeqArray', async () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const right = (n: number): _.TaskEither => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.TaskEither => + _.leftIO(() => { + log.push(s) + return s + }) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([right(1), right(2)], _.sequenceSeqArray)(), E.right([1, 2])) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([right(3), left('a')], _.sequenceSeqArray)(), E.left('a')) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([left('b'), right(4)], _.sequenceSeqArray)(), E.left('b')) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + }) }) it('match', async () => { @@ -556,4 +680,11 @@ describe('TaskEither', () => { U.deepStrictEqual(await f(_.right(1))(), 'right') U.deepStrictEqual(await f(_.left(''))(), 'left') }) + + it('chainTaskOptionK', async () => { + const f = _.chainTaskOptionK(() => 'a')((n: number) => (n > 0 ? TO.some(n * 2) : TO.none)) + U.deepStrictEqual(await pipe(_.right(1), f)(), E.right(2)) + U.deepStrictEqual(await pipe(_.right(-1), f)(), E.left('a')) + U.deepStrictEqual(await pipe(_.left('b'), f)(), E.left('b')) + }) }) diff --git a/test/TaskOption.ts b/test/TaskOption.ts index 72573ff4c..1f29c0496 100644 --- a/test/TaskOption.ts +++ b/test/TaskOption.ts @@ -1,8 +1,11 @@ -import * as U from './util' -import { pipe } from '../src/function' +import { pipe, SK } from '../src/function' import * as O from '../src/Option' +import * as RA from '../src/ReadonlyArray' +import { ReadonlyNonEmptyArray } from '../src/ReadonlyNonEmptyArray' import * as T from '../src/Task' +import * as TE from '../src/TaskEither' import * as _ from '../src/TaskOption' +import * as U from './util' describe('TaskOption', () => { // ------------------------------------------------------------------------------------- @@ -118,6 +121,15 @@ describe('TaskOption', () => { U.deepStrictEqual(await f(3)(), O.some(3)) }) + it('fromTaskEither', async () => { + const pl = TE.left('a') + const pr = TE.right('a') + const fl = _.fromTaskEither(pl) + const fr = _.fromTaskEither(pr) + U.deepStrictEqual(await fl(), O.none) + U.deepStrictEqual(await fr(), O.some('a')) + }) + // ------------------------------------------------------------------------------------- // destructors // ------------------------------------------------------------------------------------- @@ -165,48 +177,115 @@ describe('TaskOption', () => { U.deepStrictEqual(await f(_.none)(), O.none) }) - it('sequenceArray', async () => { - // tslint:disable-next-line: readonly-array - const log: Array = [] - const some = (n: number): _.TaskOption => - _.fromIO(() => { - log.push(n) - return n - }) - const none = (s: string): _.TaskOption => - pipe( - T.fromIO(() => { - log.push(s) - return s - }), - T.map(() => O.none) - ) - U.deepStrictEqual(await pipe([some(1), some(2)], _.sequenceArray)(), O.some([1, 2])) - U.deepStrictEqual(await pipe([some(3), none('a')], _.sequenceArray)(), O.none) - U.deepStrictEqual(await pipe([none('b'), some(4)], _.sequenceArray)(), O.none) - U.deepStrictEqual(log, [1, 2, 3, 'a', 'b', 4]) - }) - - it('sequenceSeqArray', async () => { - // tslint:disable-next-line: readonly-array - const log: Array = [] - const some = (n: number): _.TaskOption => - _.fromIO(() => { - log.push(n) - return n - }) - const none = (s: string): _.TaskOption => - pipe( - T.fromIO(() => { - log.push(s) - return s - }), - T.map(() => O.none) - ) - U.deepStrictEqual(await pipe([some(1), some(2)], _.sequenceSeqArray)(), O.some([1, 2])) - U.deepStrictEqual(await pipe([some(3), none('a')], _.sequenceSeqArray)(), O.none) - U.deepStrictEqual(await pipe([none('b'), some(4)], _.sequenceSeqArray)(), O.none) - U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + describe('array utils', () => { + const input: ReadonlyNonEmptyArray = ['a', 'b'] + + it('traverseReadonlyArrayWithIndex', async () => { + const f = _.traverseReadonlyArrayWithIndex((i, a: string) => (a.length > 0 ? _.some(a + i) : _.none)) + U.deepStrictEqual(await pipe(RA.empty, f)(), O.some(RA.empty)) + U.deepStrictEqual(await pipe(input, f)(), O.some(['a0', 'b1'])) + U.deepStrictEqual(await pipe(['a', ''], f)(), O.none) + }) + + it('traverseReadonlyArrayWithIndexSeq', async () => { + const f = _.traverseReadonlyArrayWithIndexSeq((i, a: string) => (a.length > 0 ? _.some(a + i) : _.none)) + U.deepStrictEqual(await pipe(RA.empty, f)(), O.some(RA.empty)) + U.deepStrictEqual(await pipe(input, f)(), O.some(['a0', 'b1'])) + U.deepStrictEqual(await pipe(['a', ''], f)(), O.none) + }) + + it('sequenceReadonlyArray', async () => { + const log: Array = [] + const some = (n: number): _.TaskOption => + _.fromIO(() => { + log.push(n) + return n + }) + const none = (s: string): _.TaskOption => + pipe( + T.fromIO(() => { + log.push(s) + return s + }), + T.map(() => O.none) + ) + U.deepStrictEqual(await pipe([some(1), some(2)], _.traverseReadonlyArrayWithIndex(SK))(), O.some([1, 2])) + U.deepStrictEqual(await pipe([some(3), none('a')], _.traverseReadonlyArrayWithIndex(SK))(), O.none) + U.deepStrictEqual(await pipe([none('b'), some(4)], _.traverseReadonlyArrayWithIndex(SK))(), O.none) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b', 4]) + }) + + it('sequenceReadonlyArraySeq', async () => { + const log: Array = [] + const some = (n: number): _.TaskOption => + _.fromIO(() => { + log.push(n) + return n + }) + const none = (s: string): _.TaskOption => + pipe( + T.fromIO(() => { + log.push(s) + return s + }), + T.map(() => O.none) + ) + U.deepStrictEqual(await pipe([some(1), some(2)], _.traverseReadonlyArrayWithIndexSeq(SK))(), O.some([1, 2])) + U.deepStrictEqual(await pipe([some(3), none('a')], _.traverseReadonlyArrayWithIndexSeq(SK))(), O.none) + U.deepStrictEqual(await pipe([none('b'), some(4)], _.traverseReadonlyArrayWithIndexSeq(SK))(), O.none) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + }) + + // old + it('sequenceArray', async () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const some = (n: number): _.TaskOption => + _.fromIO(() => { + log.push(n) + return n + }) + const none = (s: string): _.TaskOption => + pipe( + T.fromIO(() => { + log.push(s) + return s + }), + T.map(() => O.none) + ) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([some(1), some(2)], _.sequenceArray)(), O.some([1, 2])) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([some(3), none('a')], _.sequenceArray)(), O.none) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([none('b'), some(4)], _.sequenceArray)(), O.none) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b', 4]) + }) + + it('sequenceSeqArray', async () => { + // tslint:disable-next-line: readonly-array + const log: Array = [] + const some = (n: number): _.TaskOption => + _.fromIO(() => { + log.push(n) + return n + }) + const none = (s: string): _.TaskOption => + pipe( + T.fromIO(() => { + log.push(s) + return s + }), + T.map(() => O.none) + ) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([some(1), some(2)], _.sequenceSeqArray)(), O.some([1, 2])) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([some(3), none('a')], _.sequenceSeqArray)(), O.none) + // tslint:disable-next-line: deprecation + U.deepStrictEqual(await pipe([none('b'), some(4)], _.sequenceSeqArray)(), O.none) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + }) }) it('tryCatchK', async () => { diff --git a/test/TaskThese.ts b/test/TaskThese.ts index 3a89c545a..2420e365c 100644 --- a/test/TaskThese.ts +++ b/test/TaskThese.ts @@ -1,11 +1,13 @@ -import * as U from './util' -import { pipe } from '../src/function' +import * as E from '../src/Either' +import { pipe, SK } from '../src/function' import * as IO from '../src/IO' +import * as N from '../src/number' +import * as RA from '../src/ReadonlyArray' +import * as S from '../src/string' import * as T from '../src/Task' import * as _ from '../src/TaskThese' import * as TH from '../src/These' -import * as S from '../src/string' -import * as N from '../src/number' +import * as U from './util' describe('TaskThese', () => { // ------------------------------------------------------------------------------------- @@ -172,4 +174,85 @@ describe('TaskThese', () => { U.deepStrictEqual(await pipe(_.left('a'), matchE)(), 'left a') U.deepStrictEqual(await pipe(_.both('a', 1), matchE)(), 'both a 1') }) + + it('fromTheseK', async () => { + const g = _.fromTheseK((n: number) => (n > 0 ? TH.right(n) : n === 0 ? TH.both('zero', n) : TH.left('negative'))) + U.deepStrictEqual(await g(-1)(), TH.left('negative')) + U.deepStrictEqual(await g(0)(), TH.both('zero', 0)) + U.deepStrictEqual(await g(1)(), TH.right(1)) + }) + + // ------------------------------------------------------------------------------------- + // array utils + // ------------------------------------------------------------------------------------- + + it('traverseReadonlyArrayWithIndex', async () => { + const f = (i: number, n: number) => (n > 0 ? _.right(n + i) : n === 0 ? _.both('a', 0) : _.left(String(n))) + const standard = RA.traverseWithIndex(_.getApplicative(T.ApplicativePar, S.Semigroup))(f) + const optimized = _.traverseReadonlyArrayWithIndex(S.Semigroup)(f) + const assert = async (input: ReadonlyArray) => { + U.deepStrictEqual(await standard(input)(), await optimized(input)()) + } + await assert([1, 2, 3]) + await assert([0, 2, 3]) + await assert([1, 0, 3]) + await assert([0, 0, 3]) + await assert([-1, 2, 3]) + await assert([1, -2, 3]) + await assert(RA.empty) + }) + + it('traverseReadonlyArrayWithIndexSeq', async () => { + const f = (i: number, n: number) => (n > 0 ? _.right(n + i) : n === 0 ? _.both('a', 0) : _.left(String(n))) + const standard = RA.traverseWithIndex(_.getApplicative(T.ApplicativeSeq, S.Semigroup))(f) + const optimized = _.traverseReadonlyArrayWithIndexSeq(S.Semigroup)(f) + const assert = async (input: ReadonlyArray) => { + U.deepStrictEqual(await standard(input)(), await optimized(input)()) + } + await assert([1, 2, 3]) + await assert([0, 2, 3]) + await assert([1, 0, 3]) + await assert([0, 0, 3]) + await assert([-1, 2, 3]) + await assert([1, -2, 3]) + await assert(RA.empty) + }) + + it('sequenceReadonlyArray', async () => { + const log: Array = [] + const right = (n: number): _.TaskThese => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.TaskThese => + _.leftIO(() => { + log.push(s) + return s + }) + const f = _.traverseReadonlyArrayWithIndex(S.Semigroup) + U.deepStrictEqual(await pipe([right(1), right(2)], f(SK))(), E.right([1, 2])) + U.deepStrictEqual(await pipe([right(3), left('a')], f(SK))(), E.left('a')) + U.deepStrictEqual(await pipe([left('b'), right(4)], f(SK))(), E.left('b')) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b', 4]) + }) + + it('sequenceReadonlyArraySeq', async () => { + const log: Array = [] + const right = (n: number): _.TaskThese => + _.rightIO(() => { + log.push(n) + return n + }) + const left = (s: string): _.TaskThese => + _.leftIO(() => { + log.push(s) + return s + }) + const f = _.traverseReadonlyArrayWithIndexSeq(S.Semigroup) + U.deepStrictEqual(await pipe([right(1), right(2)], f(SK))(), E.right([1, 2])) + U.deepStrictEqual(await pipe([right(3), left('a')], f(SK))(), E.left('a')) + U.deepStrictEqual(await pipe([left('b'), right(4)], f(SK))(), E.left('b')) + U.deepStrictEqual(log, [1, 2, 3, 'a', 'b']) + }) }) diff --git a/test/These.ts b/test/These.ts index 790932aa7..2934fcd12 100644 --- a/test/These.ts +++ b/test/These.ts @@ -5,6 +5,7 @@ import * as N from '../src/number' import * as O from '../src/Option' import * as S from '../src/string' import * as _ from '../src/These' +import * as RA from '../src/ReadonlyArray' describe('These', () => { describe('pipeables', () => { @@ -243,4 +244,41 @@ describe('These', () => { U.deepStrictEqual(_.swap(_.right('a')), _.left('a')) U.deepStrictEqual(_.swap(_.both('a', 1)), _.both(1, 'a')) }) + + // ------------------------------------------------------------------------------------- + // array utils + // ------------------------------------------------------------------------------------- + + it('traverseReadonlyArrayWithIndex', () => { + const f = (i: number, n: number) => (n > 0 ? _.right(n + i) : n === 0 ? _.both('a', 0) : _.left(String(n))) + const standard = RA.traverseWithIndex(_.getApplicative(S.Semigroup))(f) + const optimized = _.traverseReadonlyArrayWithIndex(S.Semigroup)(f) + const assert = (input: ReadonlyArray) => { + U.deepStrictEqual(standard(input), optimized(input)) + } + assert([1, 2, 3]) + assert([0, 2, 3]) + assert([1, 0, 3]) + assert([0, 0, 3]) + assert([-1, 2, 3]) + assert([1, -2, 3]) + assert(RA.empty) + }) + + it('exists', () => { + const gt2 = _.exists((n: number) => n > 2) + U.deepStrictEqual(gt2(_.left('a')), false) + U.deepStrictEqual(gt2(_.right(1)), false) + U.deepStrictEqual(gt2(_.right(3)), true) + U.deepStrictEqual(gt2(_.both('a', 1)), false) + U.deepStrictEqual(gt2(_.both('a', 3)), true) + }) + + it('elem', () => { + U.deepStrictEqual(_.elem(N.Eq)(2)(_.left('a')), false) + U.deepStrictEqual(_.elem(N.Eq)(2)(_.right(2)), true) + U.deepStrictEqual(_.elem(N.Eq)(1)(_.right(2)), false) + U.deepStrictEqual(_.elem(N.Eq)(2)(_.both('a', 2)), true) + U.deepStrictEqual(_.elem(N.Eq)(1)(_.both('a', 2)), false) + }) }) diff --git a/test/Tree.ts b/test/Tree.ts index 6f341188f..54dd16fdf 100644 --- a/test/Tree.ts +++ b/test/Tree.ts @@ -177,20 +177,6 @@ describe('Tree', () => { ) }) - it('elem', () => { - interface User { - readonly id: number - } - const S: Eq.Eq = pipe( - N.Eq, - Eq.contramap((user: User) => user.id) - ) - const users = _.make({ id: 1 }, [_.make({ id: 1 }, [_.make({ id: 3 }), _.make({ id: 4 })]), _.make({ id: 2 })]) - U.deepStrictEqual(_.elem(S)({ id: 1 }, users), true) - U.deepStrictEqual(_.elem(S)({ id: 4 }, users), true) - U.deepStrictEqual(_.elem(S)({ id: 5 }, users), false) - }) - it('getShow', () => { const Sh = _.getShow(S.Show) const t1 = _.make('a') @@ -221,4 +207,28 @@ describe('Tree', () => { it('apS', () => { U.deepStrictEqual(pipe(_.of(1), _.bindTo('a'), _.apS('b', _.of('b'))), _.make({ a: 1, b: 'b' })) }) + + it('elem', () => { + interface User { + readonly id: number + } + const S: Eq.Eq = pipe( + N.Eq, + Eq.contramap((user: User) => user.id) + ) + const users = _.make({ id: 1 }, [_.make({ id: 1 }, [_.make({ id: 3 }), _.make({ id: 4 })]), _.make({ id: 2 })]) + U.deepStrictEqual(_.elem(S)({ id: 1 }, users), true) + U.deepStrictEqual(_.elem(S)({ id: 4 }, users), true) + U.deepStrictEqual(_.elem(S)({ id: 5 }, users), false) + }) + + it('exists', () => { + interface User { + readonly id: number + } + const users = _.make({ id: 1 }, [_.make({ id: 1 }, [_.make({ id: 3 }), _.make({ id: 4 })]), _.make({ id: 2 })]) + U.deepStrictEqual(_.exists((user: User) => user.id === 1)(users), true) + U.deepStrictEqual(_.exists((user: User) => user.id === 4)(users), true) + U.deepStrictEqual(_.exists((user: User) => user.id === 5)(users), false) + }) }) diff --git a/test/Witherable.ts b/test/Witherable.ts new file mode 100644 index 000000000..fa80b393f --- /dev/null +++ b/test/Witherable.ts @@ -0,0 +1,27 @@ +import { pipe } from '../src/function' +import * as RT from '../src/ReaderTask' +import * as RA from '../src/ReadonlyArray' +import * as RR from '../src/ReadonlyRecord' +import * as T from '../src/Task' +import * as S from '../src/string' +import * as _ from '../src/Witherable' +import * as U from './util' + +describe('Witherable', () => { + describe('filterE', () => { + const filterERA = _.filterE(RA.Witherable) + const filterERR = _.filterE(RR.getWitherable(S.Ord)) + + it('Applicative1', async () => { + const f = (n: number) => T.of(n % 2 === 0) + U.deepStrictEqual(await pipe([1, 2], filterERA(T.ApplicativePar)(f))(), [2]) + U.deepStrictEqual(await pipe({ a: 1, b: 2 }, filterERR(T.ApplicativePar)(f))(), { b: 2 }) + }) + + it('Applicative2', async () => { + const f = (n: number) => RT.of(n % 2 === 0) + U.deepStrictEqual(await pipe([1, 2], filterERA(RT.ApplicativePar)(f))({})(), [2]) + U.deepStrictEqual(await pipe({ a: 1, b: 2 }, filterERR(RT.ApplicativePar)(f))({})(), { b: 2 }) + }) + }) +}) diff --git a/test/function.ts b/test/function.ts index c8601e8bd..5d789ccf0 100644 --- a/test/function.ts +++ b/test/function.ts @@ -16,6 +16,7 @@ describe('function', () => { }) it('not', () => { + // tslint:disable-next-line: deprecation const n = _.not(Boolean) U.deepStrictEqual(n(false), true) U.deepStrictEqual(n(1), false) @@ -177,8 +178,13 @@ describe('function', () => { }) it('getEndomorphismMonoid', () => { + // tslint:disable-next-line: deprecation const M = _.getEndomorphismMonoid() const f = M.concat(_.increment, U.double) U.deepStrictEqual(f(3), 8) }) + + it('apply', () => { + U.deepStrictEqual(_.pipe(U.double, _.apply(1)), 2) + }) }) diff --git a/test/number.ts b/test/number.ts index 57652c887..d9eb86cd3 100644 --- a/test/number.ts +++ b/test/number.ts @@ -21,4 +21,8 @@ describe('string', () => { it('SemigroupProduct', () => { U.deepStrictEqual(_.SemigroupProduct.concat(2, 3), 6) }) + + it('MagmaSub', () => { + U.deepStrictEqual(_.MagmaSub.concat(2, 3), -1) + }) }) diff --git a/test/string.ts b/test/string.ts index 0a09ecbf2..3609bb1a4 100644 --- a/test/string.ts +++ b/test/string.ts @@ -1,5 +1,6 @@ import * as U from './util' import * as _ from '../src/string' +import { pipe } from '../src/function' describe('string', () => { // ------------------------------------------------------------------------------------- @@ -29,4 +30,50 @@ describe('string', () => { U.deepStrictEqual(_.size(''), 0) U.deepStrictEqual(_.size('a'), 1) }) + + it('toUpperCase', () => { + U.deepStrictEqual(_.toUpperCase('a'), 'A') + }) + + it('toLowerCase', () => { + U.deepStrictEqual(_.toLowerCase('A'), 'a') + }) + + it('replace', () => { + U.deepStrictEqual(pipe('abc', _.replace('b', 'd')), 'adc') + }) + + it('split', () => { + U.deepStrictEqual(pipe('abc', _.split('')), ['a', 'b', 'c']) + U.deepStrictEqual(pipe('', _.split('')), ['']) + }) + + it('trim', () => { + U.deepStrictEqual(pipe(' a ', _.trim), 'a') + }) + + it('trimLeft', () => { + U.deepStrictEqual(pipe(' a ', _.trimLeft), 'a ') + }) + + it('trimRight', () => { + U.deepStrictEqual(pipe(' a ', _.trimRight), ' a') + }) + + it('includes', () => { + U.deepStrictEqual(pipe('abc', _.includes('b')), true) + U.deepStrictEqual(pipe('abc', _.includes('b', 2)), false) + }) + + it('startsWith', () => { + U.deepStrictEqual(pipe('abc', _.startsWith('a')), true) + }) + + it('endsWith', () => { + U.deepStrictEqual(pipe('abc', _.endsWith('c')), true) + }) + + it('slice', () => { + U.deepStrictEqual(pipe('abcd', _.slice(1, 3)), 'bc') + }) }) diff --git a/test/struct.ts b/test/struct.ts index 8295d5d3b..73d1312aa 100644 --- a/test/struct.ts +++ b/test/struct.ts @@ -1,3 +1,4 @@ +import { pipe } from '../src/function' import * as _ from '../src/struct' import * as U from './util' @@ -17,4 +18,22 @@ describe('struct', () => { const S = _.getAssignSemigroup() U.deepStrictEqual(S.concat(foo, bar), Object.assign({}, foo, bar)) }) + + it('evolve', () => { + U.deepStrictEqual( + pipe( + { a: 'a', b: 1, c: true }, + _.evolve({ + a: (s) => s.length, + b: (b) => b > 0, + c: (c) => !c + }) + ), + { a: 1, b: true, c: false } + ) + // should ignore non own properties + const x: Record<'b', number> = Object.create({ a: 1 }) + x.b = 1 + U.deepStrictEqual(pipe(x, _.evolve({ b: (b) => b > 0 })), { b: true }) + }) }) diff --git a/tslint.json b/tslint.json index 1e8759af7..c4e921dba 100644 --- a/tslint.json +++ b/tslint.json @@ -6,7 +6,7 @@ "variable-name": false, "quotemark": [true, "single", "jsx-double"], "ter-indent": false, - "strict-boolean-expressions": true, + "strict-boolean-expressions": false, "forin": true, "no-console": true, "array-type": [true, "generic"],