/** * This file contains the Sync algebraic data type. Sync is an lazy function * that takes no inputs. In other functional languages and runtimes sync is * referred to as IO. * * @module Sync * @since 2.0.0 */ import type { $, Kind, Out } from "./kind.ts"; import type { Applicable } from "./applicable.ts"; import type { Combinable } from "./combinable.ts"; import type { Bind, Flatmappable, Tap } from "./flatmappable.ts"; import type { Initializable } from "./initializable.ts"; import type { BindTo, Mappable } from "./mappable.ts"; import type { Foldable } from "./foldable.ts"; import type { Traversable } from "./traversable.ts"; import type { Wrappable } from "./wrappable.ts"; import { constant, flow, pipe } from "./fn.ts"; import { createBind, createTap } from "./flatmappable.ts"; import { createBindTo } from "./mappable.ts"; /** * @since 2.0.0 */ export type Sync = () => A; /** * @since 2.0.0 */ export interface KindSync extends Kind { readonly kind: Sync>; } /** * @since 2.0.0 */ export function wrap(a: A): Sync { return constant(a); } /** * @since 2.0.0 */ export function apply(ua: Sync): (ta: Sync<(a: A) => I>) => Sync { return (ufai) => flow(ua, ufai()); } /** * @since 2.0.0 */ export function map(fai: (a: A) => I): (ta: Sync) => Sync { return (ta) => flow(ta, fai); } /** * @since 2.0.0 */ export function flatmap( fati: (a: A) => Sync, ): (ta: Sync) => Sync { return (ta) => flow(ta, fati, (x) => x()); } /** * @since 2.0.0 */ export function fold( foao: (o: O, a: A) => O, o: O, ): (ta: Sync) => O { return (ta) => foao(o, ta()); } /** * @since 2.0.0 */ export function traverse( A: Applicable & Mappable, ): ( faui: (a: A) => $, ) => (ta: Sync) => $, J, K], [L], [M]> { return (faui) => (ta) => pipe(faui(ta()), A.map(wrap)); } /** * @since 2.0.0 */ export function getCombinableSync( { combine }: Combinable, ): Combinable> { return { combine: (second) => (first) => () => combine(second())(first()), }; } /** * @since 2.0.0 */ export function getInitializableSync( I: Initializable, ): Initializable> { return { init: () => I.init, ...getCombinableSync(I), }; } /** * @since 2.0.0 */ export const ApplicableSync: Applicable = { apply, map, wrap }; /** * @since 2.0.0 */ export const FlatmappableSync: Flatmappable = { apply, flatmap, map, wrap, }; /** * @since 2.0.0 */ export const FoldableSync: Foldable = { fold }; /** * @since 2.0.0 */ export const MappableSync: Mappable = { map }; /** * @since 2.0.0 */ export const TraversableSync: Traversable = { map, fold, traverse }; /** * @since 2.0.0 */ export const WrappableSync: Wrappable = { wrap }; /** * @since 2.0.0 */ export const tap: Tap = createTap(FlatmappableSync); /** * @since 2.0.0 */ export const bind: Bind = createBind(FlatmappableSync); /** * @since 2.0.0 */ export const bindTo: BindTo = createBindTo(MappableSync);