import { curry } from '../curry.js' import { concat } from '../iter.js' import { Impure, pure, impure } from './free.js' /** @import {InferredMorphism, Morphism, ChainConstructor} from './types.js' */ /** * @template T * @param {T} x * @returns {x} */ export const id = x => x export const compose = curry( /** * @template T, U, V * @param {Morphism} f * @param {Morphism} g * @param {T} x * @returns V */ (f, g, x) => f(g(x)) ) export const kleisliCompose = curry( /** * @template {ChainConstructor} M, T, U * @param {M} f * @param {Morphism} g * @param {T} x * @returns U */ (f, g, x) => f(x).chain(g) ) export const lift = (...args) => args /** * @template T * @param {T} x * @returns {Impure} */ export const liftF = x => impure( x, /** @type {InferredMorphism} */(pure) ) /** * @param {number} a * @param {number} b * @returns {number} */ export const add = (a, b) => a + b /** * @template T * @param {T} x * @returns {() => T} */ export const thunk = x => () => x export const prepend = (x, xs) => concat([x], xs) export const type = x => typeof x export const is = (ctr, x) => x.constructor === ctr