diff --git a/docs/modules/Decoder.ts.md b/docs/modules/Decoder.ts.md index 5033359e8..cd173c53a 100644 --- a/docs/modules/Decoder.ts.md +++ b/docs/modules/Decoder.ts.md @@ -21,10 +21,6 @@ Added in v2.2.0 - [UnknownRecord](#unknownrecord) - [alt](#alt) - [altDecoder](#altdecoder) -- [alternativeDecoder](#alternativedecoder) -- [ap](#ap) -- [applicativeDecoder](#applicativedecoder) -- [applyDecoder](#applydecoder) - [array](#array) - [boolean](#boolean) - [failure](#failure) @@ -147,46 +143,6 @@ export declare const altDecoder: Alt1<'io-ts/Decoder'> Added in v2.2.3 -# alternativeDecoder - -**Signature** - -```ts -export declare const alternativeDecoder: Alternative1<'io-ts/Decoder'> -``` - -Added in v2.2.3 - -# ap - -**Signature** - -```ts -export declare const ap: (fa: Decoder) => (fab: Decoder<(a: A) => B>) => Decoder -``` - -Added in v2.2.0 - -# applicativeDecoder - -**Signature** - -```ts -export declare const applicativeDecoder: Applicative1<'io-ts/Decoder'> -``` - -Added in v2.2.3 - -# applyDecoder - -**Signature** - -```ts -export declare const applyDecoder: Apply1<'io-ts/Decoder'> -``` - -Added in v2.2.3 - # array **Signature** diff --git a/src/Decoder.ts b/src/Decoder.ts index 1d8f0373c..a2da8727b 100644 --- a/src/Decoder.ts +++ b/src/Decoder.ts @@ -1,9 +1,7 @@ /** * @since 2.2.0 */ -import { Alternative1 } from 'fp-ts/lib/Alternative' -import { Applicative1 } from 'fp-ts/lib/Applicative' -import { Either, either, isLeft, isRight, left, mapLeft, right } from 'fp-ts/lib/Either' +import { Either, isLeft, isRight, left, mapLeft, right } from 'fp-ts/lib/Either' import { NonEmptyArray } from 'fp-ts/lib/NonEmptyArray' import { pipe } from 'fp-ts/lib/pipeable' import { Forest, Tree } from 'fp-ts/lib/Tree' @@ -11,7 +9,6 @@ import * as G from './Guard' import { Literal, memoize, Schemable1, WithRefinement1, WithUnion1, WithUnknownContainers1 } from './Schemable' import { Functor1 } from 'fp-ts/lib/Functor' import { Alt1 } from 'fp-ts/lib/Alt' -import { Apply1 } from 'fp-ts/lib/Apply' // ------------------------------------------------------------------------------------- // model @@ -34,6 +31,10 @@ export interface Decoder { */ export type TypeOf = D extends Decoder ? A : never +// ------------------------------------------------------------------------------------- +// DecodeError +// ------------------------------------------------------------------------------------- + const empty: Array = [] /** @@ -463,28 +464,25 @@ export function union>( /** * @since 2.2.0 */ -export const alt: (that: () => Decoder) => (fa: Decoder) => Decoder = (that) => (fa) => alt_(fa, that) - -const alt_: (fx: Decoder, fy: () => Decoder) => Decoder = (fx, fy) => ({ - decode: (u) => either.alt(fx.decode(u), () => fy().decode(u)) -}) - -/** - * @since 2.2.0 - */ -export const ap: (fa: Decoder) => (fab: Decoder<(a: A) => B>) => Decoder = (fa) => (fab) => ap_(fab, fa) +export const map: (f: (a: A) => B) => (fa: Decoder) => Decoder = (f) => (fa) => map_(fa, f) -const ap_: (fab: Decoder<(a: A) => B>, fa: Decoder) => Decoder = (fab, fa) => ({ - decode: (u) => either.ap(fab.decode(u), fa.decode(u)) +const map_: (fa: Decoder, f: (a: A) => B) => Decoder = (fa, f) => ({ + decode: (u) => { + const e = fa.decode(u) + return isLeft(e) ? e : right(f(e.right)) + } }) /** * @since 2.2.0 */ -export const map: (f: (a: A) => B) => (fa: Decoder) => Decoder = (f) => (fa) => map_(fa, f) +export const alt: (that: () => Decoder) => (fa: Decoder) => Decoder = (that) => (fa) => alt_(fa, that) -const map_: (fa: Decoder, f: (a: A) => B) => Decoder = (fa, f) => ({ - decode: (u) => either.map(fa.decode(u), f) +const alt_: (fx: Decoder, fy: () => Decoder) => Decoder = (fx, fy) => ({ + decode: (u) => { + const e = fx.decode(u) + return isLeft(e) ? fy().decode(u) : e + } }) // ------------------------------------------------------------------------------------- @@ -515,25 +513,6 @@ export const functorDecoder: Functor1 = { map: map_ } -/** - * @since 2.2.3 - */ -export const applyDecoder: Apply1 = { - URI, - map: map_, - ap: ap_ -} - -/** - * @since 2.2.3 - */ -export const applicativeDecoder: Applicative1 = { - URI, - map: map_, - of, - ap: ap_ -} - /** * @since 2.2.3 */ @@ -543,18 +522,6 @@ export const altDecoder: Alt1 = { alt: alt_ } -/** - * @since 2.2.3 - */ -export const alternativeDecoder: Alternative1 = { - URI, - map: map_, - of, - ap: ap_, - alt: alt_, - zero: () => never -} - /** * @since 2.2.3 */ diff --git a/test/Codec.ts b/test/Codec.ts index a23635245..c9c30e14e 100644 --- a/test/Codec.ts +++ b/test/Codec.ts @@ -31,7 +31,7 @@ const undefinedGuard: G.Guard = { const undef: C.Codec = C.fromDecoder(D.fromGuard(undefinedGuard, 'undefined')) describe('Codec', () => { - describe('codec', () => { + describe('invariantCodec', () => { it('imap', () => { const codec = C.invariantCodec.imap( C.string, diff --git a/test/Decoder.ts b/test/Decoder.ts index 28080fac7..80ed42c95 100644 --- a/test/Decoder.ts +++ b/test/Decoder.ts @@ -4,27 +4,23 @@ import { pipe } from 'fp-ts/lib/pipeable' import * as D from '../src/Decoder' describe('Decoder', () => { - describe('decoder', () => { + it('of', () => { + const decoder = D.of(1) + assert.deepStrictEqual(decoder.decode('aaa'), E.right(1)) + }) + + describe('functorDecoder', () => { it('map', () => { const decoder = pipe( D.string, D.map((s) => s.length) ) + assert.deepStrictEqual(decoder.decode(null), E.left([D.tree('cannot decode null, should be string')])) assert.deepStrictEqual(decoder.decode('aaa'), E.right(3)) }) + }) - it('of', () => { - const decoder = D.applicativeDecoder.of(1) - assert.deepStrictEqual(decoder.decode(1), E.right(1)) - assert.deepStrictEqual(decoder.decode('a'), E.right(1)) - }) - - it('ap', () => { - const fab = D.applicativeDecoder.of((s: string): number => s.length) - const fa = D.string - assert.deepStrictEqual(pipe(fab, D.ap(fa)).decode('aaa'), E.right(3)) - }) - + describe('altDecoder', () => { it('alt', () => { const decoder = pipe( D.string, @@ -33,11 +29,6 @@ describe('Decoder', () => { assert.deepStrictEqual(decoder.decode('a'), E.right('a')) assert.deepStrictEqual(decoder.decode(1), E.right('1')) }) - - it('zero', () => { - const decoder = D.alternativeDecoder.zero() - assert.deepStrictEqual(decoder.decode(null), E.left([D.tree('cannot decode null, should be never')])) - }) }) describe('union', () => { diff --git a/test/JsonEncoder.ts b/test/JsonEncoder.ts index 9228f9afc..044f1de91 100644 --- a/test/JsonEncoder.ts +++ b/test/JsonEncoder.ts @@ -2,7 +2,7 @@ import * as assert from 'assert' import * as JE from '../src/JsonEncoder' describe('Encoder', () => { - describe('JsonEncoder', () => { + describe('contravariantJsonEncoder', () => { it('contramap', () => { const encoder = JE.contravariantJsonEncoder.contramap(JE.schemableJsonEncoder.number, (s: string) => s.length) assert.deepStrictEqual(encoder.encode('aaa'), 3)