Skip to main content Link Search Menu Expand Document (external link)

Function overview

Extension to the Effect Function module providing function introspection, lazy memoization, conditional application, and function-identity helpers.

Mental model

  • Functions are values that can be inspected, copied with a fresh identity, and partially composed.
  • All functions are pure unless explicitly noted (once and clone produce wrappers; once carries internal mutable state).

Common tasks

  • Conditional application: {@link fIfTrue}
  • Currying / shape-shifting: {@link flipDual}
  • Introspection: {@link parameterNumber}, {@link name}
  • Lazy memoization: {@link once}
  • this plumbing: {@link applyAsThis}
  • Evaluation: {@link execute}
  • Identity: {@link clone}
  • Constants: {@link constEmptyString}, {@link constFailVoid}, {@link proto}

Quickstart

Example (Curry a dual function and inspect it)

import { Array, pipe } from "effect"
import * as MFunction from "@parischap/effect-lib/MFunction"

const curriedMap = MFunction.flipDual<ReadonlyArray<number>, readonly [(n: number) => number], ReadonlyArray<number>>(
  Array.map
)
console.log(
  pipe(
    [1, 2, 3],
    curriedMap((n) => n * 2)
  )
) // [2, 4, 6]
console.log(MFunction.parameterNumber((a: number, b: number) => a + b)) // 2

Table of contents


Constants

constEmptyString

A constant lazy value always returning ''.

Signature

export declare const constEmptyString: Function.LazyArg<"">

constFailVoid

A constant lazy value always returning Result.failVoid.

  • Useful as the failure callback of helpers like Result.liftPredicate when no error context is needed.

Signature

export declare const constFailVoid: Function.LazyArg<Result.Result<never, void>>

proto

The Function.prototype object, captured via the prototype of a built-in function.

  • Useful as a reference when checking whether an object inherits from Function.prototype.

Signature

export declare const proto: Function

Utils

applyAsThis

Calls self with o bound as the this context.

  • Use to invoke a method-like function whose body relies on this.

Example (Bind this and invoke)

import { pipe } from "effect"
import * as MFunction from "@parischap/effect-lib/MFunction"

function getValue(this: { readonly value: number }) {
  return this.value
}

console.log(pipe(getValue, MFunction.applyAsThis({ value: 42 }))) // 42

Signature

export declare const applyAsThis: <O extends MTypes.ReadonlyNonPrimitive>(
  o: NoInfer<O>
) => <A>(self: (this: O) => A) => A

clone

Returns a fresh wrapper around self that exhibits the same behavior but is referentially distinct.

  • Use when downstream code keys off function identity (e.g. cache invalidation, equality checks).

Example (Distinct identity, identical behavior)

import * as MFunction from "@parischap/effect-lib/MFunction"

const original = (a: number) => a * 2
const copy = MFunction.clone(original)

console.log(original === copy) // false
console.log(original(5) === copy(5)) // true

Signature

export declare const clone: <This, Args extends ReadonlyArray<unknown>, R>(
  self: (this: This, ...args: Args) => R
) => (this: This, ...args: Args) => R

execute

Invokes a lazy value, i.e. calls self with no argument.

  • Use as the terminal step of a pipeline that builds up a LazyArg<A>.

Example (Force a lazy value)

import * as MFunction from "@parischap/effect-lib/MFunction"

console.log(MFunction.execute(() => 42)) // 42

Signature

export declare const execute: <A>(self: Function.LazyArg<A>) => A

fIfTrue

Applies f to the input value when condition is true; returns the input unchanged otherwise.

  • Use to gate a transformation by a flag without breaking the pipeline.
  • condition is captured at construction time and re-read on every call (it does not get re-evaluated — it is already a boolean).

Example (Conditional doubling)

import { pipe } from "effect"
import * as MFunction from "@parischap/effect-lib/MFunction"

const doubleIfFlag = (flag: boolean) => MFunction.fIfTrue({ condition: flag, f: (n: number) => n * 2 })

console.log(pipe(5, doubleIfFlag(true))) // 10
console.log(pipe(5, doubleIfFlag(false))) // 5

Signature

export declare const fIfTrue: <A>({
  condition,
  f
}: {
  readonly condition: boolean
  readonly f: (a: NoInfer<A>) => NoInfer<A>
}) => (a: A) => A

flipDual

Converts an n-ary, data-first function into its curried, data-first equivalent. The first argument becomes the outer parameter; the remaining arguments are taken by the returned function.

  • Use to feed a built-in Array.map-style API into a pipe chain.
  • The TypeScript inference engine cannot recover generic type parameters from a curried wrapper, so generic self’s usually require explicit type arguments at the call site.

Example (Curry Array.map)

import { Array, pipe } from "effect"
import * as MFunction from "@parischap/effect-lib/MFunction"

const curriedMap = MFunction.flipDual<ReadonlyArray<number>, readonly [(n: number) => number], ReadonlyArray<number>>(
  Array.map
)
console.log(
  pipe(
    [1, 2, 3],
    curriedMap((n) => n * 2)
  )
) // [2, 4, 6]

Signature

export declare const flipDual: <First, Others extends ReadonlyArray<unknown>, R>(
  self: (first: First, ...others: Others) => R
) => (first: First) => (...others: Others) => R

name

Returns f.name.

  • Returns an empty string for anonymous arrow expressions assigned to nothing.

Example (Function name)

import * as MFunction from "@parischap/effect-lib/MFunction"

const add = (a: number, b: number) => a + b
console.log(MFunction.name(add)) // 'add'

Signature

export declare const name: (f: MTypes.AnyFunction) => string

once

Memoizes a zero-argument function so that f runs at most once and subsequent calls return the cached result.

  • Use to defer the cost of building a constant until the first time it is actually needed, provided that constant is read more than once.
  • The wrapper holds mutable state internally; create one wrapper per cache slot.

Example (Lazy initialization)

import * as MFunction from "@parischap/effect-lib/MFunction"

let calls = 0
const expensive = MFunction.once(() => {
  calls++
  return 42
})

console.log(expensive()) // 42
console.log(expensive()) // 42
console.log(calls) // 1

Signature

export declare const once: <A>(f: Function.LazyArg<A>) => Function.LazyArg<A>

parameterNumber

Returns the declared arity of f (i.e. f.length).

  • Returns the number of named parameters before the first one with a default value or the rest parameter.

Example (Declared arity)

import * as MFunction from "@parischap/effect-lib/MFunction"

console.log(MFunction.parameterNumber((a: number, b: number) => a + b)) // 2
console.log(MFunction.parameterNumber((a: number) => a)) // 1

Signature

export declare const parameterNumber: (f: MTypes.AnyFunction) => number