/** * @category instances * @since 0.24.0 */ import { dual } from "effect/Function" import type { Kind, TypeLambda } from "effect/HKT" import * as Option from "effect/Option" import type * as alternative from "../Alternative.js" import type * as applicative from "../Applicative.js" import type * as chainable from "../Chainable.js" import type * as coproduct_ from "../Coproduct.js" import * as covariant from "../Covariant.js" import type * as filterable from "../Filterable.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 { Monoid } from "../Monoid.js" import * as monoid from "../Monoid.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 * as semigroup from "../Semigroup.js" import type * as semiProduct from "../SemiProduct.js" import type * as traversable from "../Traversable.js" const of = Option.some const map = Option.map const flatMap = Option.flatMap const productAll = Option.all const coproductAll = Option.firstSomeOf const zero = Option.none const product = Option.product const productMany = Option.productMany const imap = covariant.imap(map) const coproduct = (self: Option.Option, that: Option.Option): Option.Option => Option.isSome(self) ? self : that const coproductMany = ( self: Option.Option, collection: Iterable> ): Option.Option => Option.isSome(self) ? self : Option.firstSomeOf(collection) const traverse = ( F: applicative.Applicative ): { ( f: (a: A) => Kind ): (self: Option.Option) => Kind> ( self: Option.Option, f: (a: A) => Kind ): Kind> } => dual( 2, ( self: Option.Option, f: (a: A) => Kind ): Kind> => Option.isNone(self) ? F.of(Option.none()) : F.map(f(self.value), Option.some) ) /** * @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 } /** * @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 } /** * @category instances * @since 0.24.0 */ export const SemiCoproduct: semiCoproduct.SemiCoproduct = { imap, coproduct, coproductMany } /** * @category instances * @since 0.24.0 */ export const Coproduct: coproduct_.Coproduct = { imap, coproduct, coproductMany, zero, coproductAll } /** * @category instances * @since 0.24.0 */ export const SemiAlternative: semiAlternative.SemiAlternative = { map, imap, coproduct, coproductMany } /** * @category instances * @since 0.24.0 */ export const Alternative: alternative.Alternative = { map, imap, coproduct, coproductMany, coproductAll, zero } /** * @category instances * @since 0.24.0 */ export const Foldable: foldable.Foldable = { reduce: dual( 3, (self: Option.Option, b: B, f: (b: B, a: A) => B): B => Option.isNone(self) ? b : f(b, self.value) ) } /** * @category instances * @since 0.24.0 */ export const Filterable: filterable.Filterable = { partitionMap: Option.partitionMap, filterMap: Option.filterMap } /** * @category instances * @since 0.24.0 */ export const Traversable: traversable.Traversable = { traverse } /** * @category instances * @since 0.24.0 */ export const getOptionalMonoid = ( Semigroup: Semigroup ): Monoid> => monoid.fromSemigroup( semigroup.make((self, that) => Option.isNone(self) ? that : Option.isNone(that) ? self : Option.some(Semigroup.combine(self.value, that.value)) ), Option.none() )