/**
* @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
}