import type * as P from "@principia/prelude"; import { apF_, chainF_, pureF } from "@principia/prelude"; import type * as HKT from "@principia/prelude/HKT"; import { _intersect, memoize } from "../_utils"; import * as A from "../Array"; import * as E from "../Either"; import type { Option } from "../Option"; import { none, some } from "../Option"; import * as R from "../Record"; import { fromRefinement } from "./constructors"; import type { InputOf, KleisliDecoder, KleisliDecoderHKT, TypeOf } from "./model"; export function mapLeftWithInput_( M: P.Bifunctor ): (decoder: KleisliDecoder, f: (i: I, e: E) => E) => KleisliDecoder { return (decoder, f) => ({ decode: (i) => M.first_(decoder.decode(i), (e) => f(i, e)) }); } export function mapLeftWithInput( M: P.Bifunctor ): (f: (i: I, e: E) => E) => (decoder: KleisliDecoder) => KleisliDecoder { return (f) => (decoder) => mapLeftWithInput_(M)(decoder, f); } export function compose_( M: P.Monad> ): (ia: KleisliDecoder, ab: KleisliDecoder) => KleisliDecoder; export function compose_( M: P.Monad, HKT.Fix<"E", E>> ): (ia: KleisliDecoderHKT, ab: KleisliDecoderHKT) => KleisliDecoderHKT { return (ia, ab) => ({ decode: (i0) => chainF_(M)(ia.decode(i0), ab.decode) }); } export function compose( M: P.Monad> ): ( ab: KleisliDecoder ) => (ia: KleisliDecoder) => KleisliDecoder; export function compose( M: P.Monad, HKT.Fix<"E", E>> ): ( ab: KleisliDecoderHKT ) => (ia: KleisliDecoderHKT) => KleisliDecoderHKT { return (ab) => (ia) => compose_(M)(ia, ab); } export function refine_( M: P.MonadFail> ): ( from: KleisliDecoder, refinement: (a: A) => a is B, onError: (a: A) => E ) => KleisliDecoder; export function refine_(M: P.MonadFail, HKT.Fix<"E", E>>) { return ( from: KleisliDecoderHKT, refinement: (a: A) => a is A, onError: (a: A) => E ): KleisliDecoderHKT => compose_(M)(from, fromRefinement(M)(refinement, onError)); } export function refine( M: P.MonadFail> ): ( refinement: (a: A) => a is B, onError: (a: A) => E ) => (from: KleisliDecoder) => KleisliDecoder; export function refine(M: P.MonadFail, HKT.Fix<"E", E>>) { return (refinement: (a: A) => a is A, onError: (a: A) => E) => ( from: KleisliDecoderHKT ): KleisliDecoderHKT => refine_(M)(from, refinement, onError); } export function parse_( M: P.Monad> ): ( from: KleisliDecoder, decode: ( a: A ) => HKT.Kind< M, C, HKT.Initial, HKT.Initial, HKT.Initial, HKT.Initial, HKT.Initial, HKT.Initial, HKT.Initial, HKT.Initial, E, B > ) => KleisliDecoder; export function parse_( M: P.Monad, HKT.Fix<"E", E>> ): ( from: KleisliDecoderHKT, decode: (a: A) => HKT.HKT2 ) => KleisliDecoderHKT { return (from, decode) => compose_(M)(from, { decode }); } export function parse( M: P.Monad> ): ( decode: ( a: A ) => HKT.Kind< M, C, HKT.Initial, HKT.Initial, HKT.Initial, HKT.Initial, HKT.Initial, HKT.Initial, HKT.Initial, HKT.Initial, E, B > ) => (from: KleisliDecoder) => KleisliDecoder; export function parse( M: P.Monad, HKT.Fix<"E", E>> ): ( decode: (a: A) => HKT.HKT2 ) => (from: KleisliDecoderHKT) => KleisliDecoderHKT { return (decode) => (from) => parse_(M)(from, decode); } export function nullable_( M: P.Applicative> & P.Bifunctor> ): ( or: KleisliDecoder, onError: (i: I, e: E) => E ) => KleisliDecoder; export function nullable_( M: P.Applicative, HKT.Fix<"E", E>> & P.Bifunctor> ): ( or: KleisliDecoderHKT, onError: (i: I, e: E) => E ) => KleisliDecoderHKT { return (or, onError) => ({ decode: (i) => i == null ? pureF(M)(null) : M.bimap_( or.decode(i), (e: E) => onError(i, e), (a) => a ) }); } export function nullable( M: P.Applicative> & P.Bifunctor> ): ( onError: (i: I, e: E) => E ) => (or: KleisliDecoder) => KleisliDecoder; export function nullable( M: P.Applicative, HKT.Fix<"E", E>> & P.Bifunctor> ): ( onError: (i: I, e: E) => E ) => (or: KleisliDecoderHKT) => KleisliDecoderHKT { return (onError) => (or) => nullable_(M)(or, onError); } export function optional_( M: P.Applicative> & P.Bifunctor> ): ( or: KleisliDecoder, onError: (i: I, e: E) => E ) => KleisliDecoder>; export function optional_( M: P.Applicative, HKT.Fix<"E", E>> & P.Bifunctor> ): ( or: KleisliDecoderHKT, onError: (i: I, e: E) => E ) => KleisliDecoderHKT> { return (or, onError) => ({ decode: (i) => i == null ? pureF(M)(none()) : M.bimap_( or.decode(i), (e) => onError(i, e), (a) => some(a) ) }); } export function optional( M: P.Applicative> & P.Bifunctor> ): ( onError: (i: I, e: E) => E ) => (or: KleisliDecoder) => KleisliDecoder>; export function optional( M: P.Applicative, HKT.Fix<"E", E>> & P.Bifunctor> ): ( onError: (i: I, e: E) => E ) => (or: KleisliDecoderHKT) => KleisliDecoderHKT> { return (onError) => (or) => optional_(M)(or, onError); } export function fromType_( M: P.Applicative> & P.Bifunctor> ):

>>( properties: P, onPropertyError: (key: string, e: E) => E ) => KleisliDecoder }, E, { [K in keyof P]: TypeOf }>; export function fromType_( M: P.Applicative, HKT.Fix<"E", E>> & P.Bifunctor> ):

>>( properties: P, onPropertyError: (key: string, e: E) => E ) => KleisliDecoderHKT { return (properties, onPropertyError) => ({ decode: (i) => R.traverseWithIndex_(M)(properties, (key, decoder) => M.first_(decoder.decode(i[key]), (e) => onPropertyError(key, e)) ) as any }); } export function fromType( M: P.Applicative> & P.Bifunctor> ): ( onPropertyError: (key: string, e: E) => E ) =>

>>( properties: P ) => KleisliDecoder }, E, { [K in keyof P]: TypeOf }>; export function fromType( M: P.Applicative, HKT.Fix<"E", E>> & P.Bifunctor> ): ( onPropertyError: (key: string, e: E) => E ) =>

>>( properties: P ) => KleisliDecoderHKT { return (onPropertyError) => (properties) => fromType_(M)(properties, onPropertyError); } export function fromPartial_( M: P.Applicative> & P.Bifunctor> ):

>>( properties: P, onPropertyError: (key: string, e: E) => E ) => KleisliDecoder< M, C, Partial<{ [K in keyof P]: InputOf }>, E, Partial<{ [K in keyof P]: TypeOf }> >; export function fromPartial_( M: P.Applicative, HKT.Fix<"E", E>> & P.Bifunctor> ):

>>( properties: P, onPropertyError: (key: string, e: E) => E ) => KleisliDecoderHKT, E, Partial<{ [K in keyof P]: any }>> { const traverse = R.traverseWithIndex_(M); const pure = pureF(M); const undefinedProperty = pure(E.right(undefined)); const skipProperty = pure(E.left(undefined)); return (properties, onPropertyError) => ({ decode: (i) => M.map_( traverse(properties, (key, decoder) => { const ikey = i[key]; if (ikey === undefined) { return key in i ? undefinedProperty : skipProperty; } return M.bimap_( decoder.decode(ikey), (e) => onPropertyError(key, e), (a) => E.right(a) ); }), compactRecord ) as any }); } export function fromPartial( M: P.Applicative> & P.Bifunctor> ): ( onPropertyError: (key: string, e: E) => E ) =>

>>( properties: P ) => KleisliDecoder< M, C, Partial<{ [K in keyof P]: InputOf }>, E, Partial<{ [K in keyof P]: TypeOf }> >; export function fromPartial( M: P.Applicative, HKT.Fix<"E", E>> & P.Bifunctor> ): ( onPropertyError: (key: string, e: E) => E ) =>

>>( properties: P ) => KleisliDecoderHKT, E, Partial<{ [K in keyof P]: any }>> { const fromPartialM = fromPartial_(M); return (onPropertyError) => (properties) => fromPartialM(properties, onPropertyError); } export function fromArray_( M: P.Applicative> & P.Bifunctor> ): ( item: KleisliDecoder, onItemError: (index: number, e: E) => E ) => KleisliDecoder, E, ReadonlyArray>; export function fromArray_( M: P.Applicative, HKT.Fix<"E", E>> & P.Bifunctor, HKT.Fix<"E", E>> ): ( item: KleisliDecoderHKT, onItemError: (index: number, e: E) => E ) => KleisliDecoderHKT, E, ReadonlyArray> { const traverse = A.traverseWithIndex_(M); return (item, onItemError) => ({ decode: (is) => traverse(is, (index, i) => M.first_(item.decode(i), (e: E) => onItemError(index, e))) }); } export function fromArray( M: P.Applicative> & P.Bifunctor> ): ( onItemError: (index: number, e: E) => E ) => (item: KleisliDecoder) => KleisliDecoder, E, ReadonlyArray>; export function fromArray( M: P.Applicative, HKT.Fix<"E", E>> & P.Bifunctor> ): ( onItemError: (index: number, e: E) => E ) => (item: KleisliDecoderHKT) => KleisliDecoderHKT, E, ReadonlyArray> { const fromArrayM = fromArray_(M); return (onItemError) => (item) => fromArrayM(item, onItemError); } export function fromRecord_( M: P.Applicative> & P.Bifunctor> ): ( codomain: KleisliDecoder, onKeyError: (key: string, e: E) => E ) => KleisliDecoder, E, Record>; export function fromRecord_( M: P.Applicative, HKT.Fix<"E", E>> & P.Bifunctor> ): ( codomain: KleisliDecoderHKT, onKeyError: (key: string, e: E) => E ) => KleisliDecoderHKT, E, Record> { const traverse = R.traverseWithIndex_(M); return (codomain, onKeyError) => ({ decode: (ir) => traverse(ir, (key, i) => M.first_(codomain.decode(i as any), (e) => onKeyError(key, e))) }); } export function fromRecord( M: P.Applicative> & P.Bifunctor> ): ( onKeyError: (key: string, e: E) => E ) => (codomain: KleisliDecoder) => KleisliDecoder, E, Record>; export function fromRecord( M: P.Applicative, HKT.Fix<"E", E>> & P.Bifunctor> ): ( onKeyError: (key: string, e: E) => E ) => (codomain: KleisliDecoderHKT) => KleisliDecoderHKT, E, Record> { const fromRecordM = fromRecord_(M); return (onKeyError) => (codomain) => fromRecordM(codomain, onKeyError); } export function fromTuple( M: P.Applicative> & P.Bifunctor ): ( onIndexError: (index: number, e: E) => E ) =>

>>( ...components: P ) => KleisliDecoder }, E, { [K in keyof P]: TypeOf }>; export function fromTuple( M: P.Applicative, HKT.Fix<"E", E>> & P.Bifunctor> ): ( onIndexError: (index: number, e: E) => E ) =>

>>( ...components: P ) => KleisliDecoderHKT { const traverse = A.traverseWithIndex_(M); return (onIndexError) => (...components) => ({ decode: (is) => traverse(components, (index, decoder) => M.first_(decoder.decode(is[index]), (e) => onIndexError(index, e)) ) as any }); } export function union( M: P.Alt> & P.Bifunctor ): ( onMemberError: (index: number, e: E) => E ) =>

, ...ReadonlyArray>]>( ...members: P ) => KleisliDecoder, E, TypeOf>; export function union( M: P.Alt, HKT.Fix<"E", E>> & P.Bifunctor> ): ( onMemberError: (index: number, e: E) => E ) =>

, ...ReadonlyArray>]>( ...components: P ) => KleisliDecoderHKT { return (onMemberError) => (...members) => ({ decode: (i) => { let out = M.first_(members[0].decode(i), (e) => onMemberError(0, e)); for (let index = 1; index < members.length; index++) { out = M.alt_(out, () => M.first_(members[index].decode(i), (e) => onMemberError(index, e))); } return out; } }); } export function intersect_( M: P.Applicative> ): ( left: KleisliDecoder, right: KleisliDecoder ) => KleisliDecoder; export function intersect_( M: P.Applicative, HKT.Fix<"E", E>> ): ( ia: KleisliDecoderHKT, ab: KleisliDecoderHKT ) => KleisliDecoderHKT { const ap = apF_(M); return ( left: KleisliDecoderHKT, right: KleisliDecoderHKT ): KleisliDecoderHKT => ({ decode: (i) => ap( M.map_(left.decode(i), (a: A) => (b: B) => _intersect(a, b)), right.decode(i) ) }); } export function intersect( M: P.Applicative> ): ( right: KleisliDecoder ) => (left: KleisliDecoder) => KleisliDecoder; export function intersect( M: P.Applicative, HKT.Fix<"E", E>> ): ( right: KleisliDecoderHKT ) => (left: KleisliDecoderHKT) => KleisliDecoderHKT { return (right) => (left) => intersect_(M)(left, right); } export function fromSum_( M: P.MonadFail> ): >>( tag: T, members: P, onTagError: (tag: string, vaue: unknown, tags: ReadonlyArray) => E ) => KleisliDecoder, E, TypeOf>; export function fromSum_( M: P.MonadFail, HKT.Fix<"E", E>> ): >>( tag: T, members: P, onTagError: (tag: string, value: unknown, tags: ReadonlyArray) => E ) => KleisliDecoderHKT { return (tag, members, onTagError) => { const keys = Object.keys(members); return { decode: (ir) => { const v = ir[tag]; if (v in members) { return (members as any)[v].decode(ir); } return M.fail(onTagError(tag, v, keys)); } }; }; } export function fromSum( M: P.MonadFail> ): ( onTagError: (tag: string, value: unknown, tags: ReadonlyArray) => E ) => ( tag: T ) =>

>>( members: P ) => KleisliDecoder, E, TypeOf>; export function fromSum( M: P.MonadFail, HKT.Fix<"E", E>> ): ( onTagError: (tag: string, value: unknown, tags: ReadonlyArray) => E ) => ( tag: T ) =>

>>(members: P) => KleisliDecoderHKT { return (onTagError) => (tag) => (members) => fromSum_(M)(tag, members, onTagError); } export function lazy_( M: P.Bifunctor ): ( id: string, f: () => KleisliDecoder, I, E, A>, onError: (id: string, e: E) => E ) => KleisliDecoder, I, E, A>; export function lazy_( M: P.Bifunctor> ): ( id: string, f: () => KleisliDecoderHKT, onError: (id: string, e: E) => E ) => KleisliDecoderHKT { return ( id: string, f: () => KleisliDecoderHKT, onError: (id: string, e: E) => E ): KleisliDecoderHKT => { const get = memoize>(f); return { decode: (i) => M.first_(get().decode(i), (e: E) => onError(id, e)) }; }; } export function lazy( M: P.Bifunctor ): ( onError: (id: string, e: E) => E ) => ( id: string, f: () => KleisliDecoder, I, E, A> ) => KleisliDecoder, I, E, A>; export function lazy( M: P.Bifunctor> ): ( onError: (id: string, e: E) => E ) => (id: string, f: () => KleisliDecoderHKT) => KleisliDecoderHKT { return (onError) => (id, f) => lazy_(M)(id, f, onError); } export const id = (M: P.Applicative>) => (): KleisliDecoder< M, C, A, E, A > => ({ decode: pureF(M) }); export const map_ = (F: P.Functor>) => ( ia: KleisliDecoder, f: (a: A) => B ): KleisliDecoder => ({ decode: (i) => F.map_(ia.decode(i), f) }); export const map = (F: P.Functor>) => (f: (a: A) => B) => ( ia: KleisliDecoder ): KleisliDecoder => map_(F)(ia, f); export function alt_( A: P.Alt> ): ( me: KleisliDecoder, that: () => KleisliDecoder ) => KleisliDecoder; export function alt_( A: P.Alt, HKT.Fix<"E", E>> ): ( me: KleisliDecoderHKT, that: () => KleisliDecoderHKT ) => KleisliDecoderHKT { return (me, that) => ({ decode: (i) => A.alt_(me.decode(i), () => that().decode(i)) }); } export function alt( A: P.Alt> ): ( that: () => KleisliDecoder ) => (me: KleisliDecoder) => KleisliDecoder; export function alt( A: P.Alt, HKT.Fix<"E", E>> ): ( that: () => KleisliDecoderHKT ) => (me: KleisliDecoderHKT) => KleisliDecoderHKT { return (that) => (me) => alt_(A)(me, that); } const compactRecord = (r: Record>): Record => { const out: Record = {}; for (const k in r) { const rk = r[k]; if (E.isRight(rk)) { out[k] = rk.right; } } return out; };