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

Function.ts 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: fIfTrue
  • Currying / shape-shifting: flipDual
  • Introspection: parameterNumber, name
  • Lazy memoization: once
  • this plumbing: applyAsThis
  • Evaluation: execute
  • Identity: clone
  • Constants: constEmptyString, constFailVoid, proto

Quickstart

Example (Curry a dual function and inspect it)

import { Array, pipe, String } from "effect"

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

const curriedTakeLeft = MFunction.flipDual(String.takeLeft)
console.log(pipe(2, curriedTakeLeft("foo"))) // 'fo'
console.log(MFunction.parameterNumber((a: number, b: number) => a + b)) // 2

Exports Grouped by Category


Constants

Function

The original function object

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

Signature

declare const Function: FunctionConstructor

Source

constEmptyString

A constant lazy value always returning ''.

Signature

declare const constEmptyString: Function.LazyArg<"">

Source

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

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

Source

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

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

Source

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

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

Source

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

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

Source

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) => pipe(5, MFunction.fIfTrue({ condition: flag, f: (n: number) => n * 2 }))

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

Signature

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

Source

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, String } from "effect"

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

const curriedTakeLeft = MFunction.flipDual(String.takeLeft)
console.log(pipe(2, curriedTakeLeft("foo"))) // 'fo'

Signature

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

Source

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

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

Source

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

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

Source

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

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

Source