/** * @since 0.24.0 */ import * as readonlyArray from "effect/Array" import { dual, identity } from "effect/Function" import type { Kind, TypeLambda } from "effect/HKT" import type * as applicative from "../Applicative.js" import type * as chainable from "../Chainable.js" import * as covariant from "../Covariant.js" import type * as flatMap_ from "../FlatMap.js" import type * as foldable from "../Foldable.js" import type * as invariant from "../Invariant.js" import type * as monad from "../Monad.js" import type * as of_ from "../Of.js" import type * as pointed from "../Pointed.js" import type * as product_ from "../Product.js" import type * as semiAlternative from "../SemiAlternative.js" import type * as semiApplicative from "../SemiApplicative.js" import type * as semiCoproduct from "../SemiCoproduct.js" import type { Semigroup } from "../Semigroup.js" import type * as semiProduct from "../SemiProduct.js" import type * as traversable from "../Traversable.js" const of: (a: A) => Identity = identity const map: { (f: (a: A) => B): (self: Identity) => Identity (self: Identity, f: (a: A) => B): Identity } = dual(2, (self: Identity, f: (a: A) => B): Identity => f(self)) const imap = covariant.imap(map) const flatMap: { (f: (a: A) => B): (self: Identity) => Identity (self: Identity, f: (a: A) => B): Identity } = dual(2, (self: Identity, f: (a: A) => B): Identity => f(self)) const product = (self: Identity, that: Identity): Identity<[A, B]> => [self, that] const productMany = ( self: Identity, collection: Iterable ): [A, ...Array] => [self, ...collection] const traverse = ( F: applicative.Applicative ): { (f: (a: A) => Kind): (self: Identity) => Kind (self: Identity, f: (a: A) => Kind): Kind } => dual( 2, (self: Identity, f: (a: A) => Kind): Kind => f(self) ) /** * @category models * @since 0.24.0 */ export type Identity = A /** * @category type lambdas * @since 0.24.0 */ export interface IdentityTypeLambda extends TypeLambda { readonly type: Identity } /** * @category type lambdas * @since 0.24.0 */ export interface IdentityTypeLambdaFix extends TypeLambda { readonly type: Identity } /** * @category instances * @since 0.24.0 */ export const Covariant: covariant.Covariant = { imap, map } /** * @category instances * @since 0.24.0 */ export const Invariant: invariant.Invariant = { imap } /** * @category instances * @since 0.24.0 */ export const Of: of_.Of = { of } /** * @category instances * @since 0.24.0 */ export const Pointed: pointed.Pointed = { of, imap, map } /** * @category instances * @since 0.24.0 */ export const FlatMap: flatMap_.FlatMap = { flatMap } /** * @category instances * @since 0.24.0 */ export const Chainable: chainable.Chainable = { imap, map, flatMap } /** * @category instances * @since 0.24.0 */ export const Monad: monad.Monad = { imap, of, map, flatMap } /** * @category instances * @since 0.24.0 */ export const SemiProduct: semiProduct.SemiProduct = { imap, product, productMany } /** * @category instances * @since 0.24.0 */ export const Product: product_.Product = { of, imap, product, productMany, productAll: readonlyArray.fromIterable } /** * @category instances * @since 0.24.0 */ export const SemiApplicative: semiApplicative.SemiApplicative = { imap, map, product, productMany } /** * @category instances * @since 0.24.0 */ export const Applicative: applicative.Applicative = { imap, of, map, product, productMany, productAll: readonlyArray.fromIterable } /** * @category instances * @since 0.24.0 */ export const getSemiCoproduct = ( S: Semigroup ): semiCoproduct.SemiCoproduct> => ({ imap, coproduct: dual(2, S.combine), coproductMany: dual(2, S.combineMany) }) /** * @category instances * @since 0.24.0 */ export const getSemiAlternative = ( S: Semigroup ): semiAlternative.SemiAlternative> => ({ ...getSemiCoproduct(S), map }) /** * @category instances * @since 0.24.0 */ export const Foldable: foldable.Foldable = { reduce: dual(3, (self: Identity, b: B, f: (b: B, a: A) => B): B => f(b, self)) } /** * @category instances * @since 0.24.0 */ export const Traversable: traversable.Traversable = { traverse }