npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

functional-concepts

v0.0.1

Published

Библиотека с набором функций для возможности использования некоторых приемов функционального программирования

Readme

functional-concepts

Библиотека с набором функций для возможности использования некоторых приемов функционального программирования.

В состав входят следующие функции:

  • compose
  • curry
  • flip
  • is
  • memoize
  • partial
  • pipe
  • concat
  • each
  • filter
  • find
  • findIndex
  • last
  • map
  • reduce
  • reduceRight
  • reverse
  • sort
  • unique
  • zip

А также их каррированные варианты.

Установка

NPM:

npm install functional-concepts

Использование

// классические варианты функций
import { /* имена функций */ } from 'functional-concepts'

// каррированные варианты функций
import { /* имена функций */ } from 'functional-concepts/curried'

Примеры использования

В дальнейших примерах будем оперировать массивом объектов описывающих машины. Каждая машина представлена объектом следующего вида:

{
    name: 'Aston Martin One-77',
    horsePower: 750,
    maxSpeed: 220,
    price: 1850000,
    inStock: true
}

Каррирование

Функция curry(f, arity = f.length) преобразует функцию в набор функций с единственным аргументом.

Рассмотрим вариант функции без каррирования:

// функция с двумя аргументами
const map = (f, array) => array.map(f)
// деталь
const getPrices = cars => map(car => car.price, cars) // не очень удобно создавать детали - над именами аргументов приходится подумать

Применим каррирование:

// каррированная функция
const map = curry((f, array) => array.map(f))
// деталь
const getPrices = map(car => car.price) // уже лучше

Можем использовать бесточечный стиль (point-free style):

// вспомогательная функция
const prop = curry((name, obj) => obj[name]) // можно переиспользовать
// селектор
const selectPrice = prop('price') // можно переиспользовать
// деталь
const getPrices = map(selectPrice) // бесточечный стиль, выглядит кратко и лаконично

Пример использования:

console.log(getPrices(getCars()))

Несмотря на то, что в классическом понимании каррирование преобразует функцию в набор функций с единственным параметром, на практике реализации каррирования могут принимать несколько аргументов за раз:

const sum = (x, y, z) => x + y + z
const curriedSum = curry(sum)
curriedSum(8, 13)(21) // 42
curriedSum(8)(13, 21) // 42
curriedSum(8, 13, 21) // 42

Частичное применение

Функция partial(f, ...args) преобразует функцию с некоторым числом аргументов в функцию с меньшим числом аргументов.

// функции с двумя аргументами
const map = (f, array) => array.map(f)
const prop = (name, obj) => obj[name]

// частичное применение
const selectPrice = partial(prop, 'price')
const getPrices = partial(map, selectPrice)

console.log(getPrices(getCars())) // пример использования

В отличии от каррированной функции, в функцию с частичным применением нужно передать все недостающие параметры:

const sum = (x, y, z) => x + y + z
const partialSum = partial(sum, 8)
partialSum(13, 21) // 42 т.к. выполнится sum(8, 13, 21)
partialSum(13) // NaN т.к. выполнится sum(8, 13, undefined)

Композиция

Функция compose(...fs) возвращает функцию, аргумент которой последовательно проходит справа налево:

Определим функции с которыми будем работать в примере:

const add = (x, y) => x + y
const map = (f, array) => array.map(f)
const reduce = (f, array) => array.reduce(f)

// вспомогательная функция, вычисляющая среднее арифметическое из значений в массиве
const average = xs => reduce(add, xs) / xs.length

Без композиции деталь была бы такой:

// деталь
const getAveragePrice = cars => average(map(car => car.price, cars))

Используем композицию:

// деталь
const getAveragePrice = compose(average, map(car => car.price)) // уже лучше

В бесточечном стиле:

// вспомогательная функция
const prop = name => obj => obj[name] // можно переиспользовать
// селектор
const selectPrice = prop('price') // можно переиспользовать
// деталь в бесточечном стиле
const getAveragePrice = compose(average, map(selectPrice)) // еще лучше

Пример использования:

console.log(getAveragePrice(getCars()))

Конвейер

Функция pipe(...fs) возвращает функцию аргумент которой, последовательно проходит слева направо:

const sort = xs => [...xs].sort()
const last = xs => xs[xs.length - 1]
const selectMaxSpeed = prop('maxSpeed')

// деталь
const getFastestCar = pipe(map(selectMaxSpeed), sort, last) // конвейер

console.log(getFastestCar(getCars())) // пример использования

Порядок выполнения функций в конвейере отличается от порядка выполнения функций в композиции:

// оригинальная цепочка вызовов
three(two(one(x)))

// более естественно с точки зрения чтения
pipe(one, two, three)(x)

// более естественно с точки зрения записи
compose(three, two, one)(x)

Мемоизация

Это полезный приём, при котором функция кеширует результаты своего вызова, чтобы не выполнять повторяющиеся вычисления. Функция memoize(f, cache = new Map) возвращает функцию кеширующую результаты выполнения оригинальной функции.

Пример без мемоизации:

const f = x => x * x
f(2) // вычислить
f(2) // вычислить
f(2) // вычислить

С мемоизацией:

const f = memoize(x => x * x)
f(2) // вычислить
f(2) // взять из кеша
f(2) // взять из кеша

Проверка типа

Функция is(type, x) - это предикат, проверяющий принадлежность своего аргумента x к определенному классу type.

const elements = [...document.body.children].filter(is(Element))

Изменение порядка аргументов

Функция flip(f) меняет порядок аргументов. Иногда это бывает полезно.

const pipe = flip(compose)

Тестирование при разработке

npm test

Лицензия

MIT