Узел карри с назначенным ему ленивым значением - PullRequest
2 голосов
/ 04 июня 2019

У меня есть такая функция, как ...

const constant = v => () => v;

И у меня есть значение, подобное ...

let someGlobalValue;

А потом у меня есть еще одна const, как ...

const curriedFunction = constant(someGlobalValue);

Теперь ... когда я сделаю это ...

someGlobalValue = 123;
consoleLog(curriedFunction());

Вывод будет undefined.

Я знаю, почему это так.Это потому, что я уже создал экземпляр функции curried с сохраненным значением, когда файл загружен, и он установлен в этой точке.Таким образом, изменение someGlobalValue не читается во время вызова функции карри.

Но ... есть ли способ этого не делать?

Мне нужно иметь возможностьустановите someGlobalValue перед вызовом функции карри, чтобы она возвращала только что установленное значение.Но я не могу понять, как это сделать.

Спасибо

Ответы [ 4 ]

2 голосов
/ 04 июня 2019

Мне нужно установить someGlobalValue перед вызовом функции карри и вернуть ей значение, которое я только что установил.Но я не могу понять, как это сделать.

Извините, но это противоположность функциональной дисциплины.В функциональном стиле функции обеспечивают ссылочную прозрачность, при которой функция всегда дает один и тот же результат, когда ей передаются одинаковые аргументы.Функция, которую вы описываете, нечиста, поскольку она может давать другой результат, в зависимости от состояния someGlobalValue.

Еще одна подсказка заключается в названии функции constant.Когда мы используем константу , программист полагается на то, что значение не изменится.

Наконец, ваша переменная curriedFunction названа плохо.Это не функция карри, поэтому это имя только сбивает вас с толку.

let someGlobalValue = 1

const impureFunction = () => someGlobalValue

console.log(impureFunction())
// 1

someGlobalValue = 2

console.log(impureFunction())
// 2

Ваш вопрос очень тесно связан с крошечной гранулой кода.Если вы сможете поделиться с вами контекстом и показать нам, как вы собираетесь использовать эти гранулы, мы сможем предложить более эффективный совет.

2 голосов
/ 04 июня 2019

У меня есть такая функция ...

const constant = v => () => v;

хорошая утилита, если вы хотите всегда возвращать постоянное значение. Но это не то, что вы хотите здесь.

Самое простое решение:

const curriedFunction = () => someGlobalValue;

, тогда curriedFunction() всегда будет возвращать значение someGlobalValue, даже если вы измените его.

2 голосов
/ 04 июня 2019

Вы можете передать ссылку на объект и установить значение в объекте позже. Но это не рекомендуется, потому что это смущает читателя.

const constant = o => () => o.value;
const someGlobalValue = {};
const curriedFunction = constant(someGlobalValue);

someGlobalValue.value = 123;

console.log(curriedFunction());
1 голос
/ 04 июня 2019

Если это действительно глобальная (или, по крайней мере, внутренняя) переменная, и вам нужна текущая ее версия при вызове curriedFunction, вы вообще не хотите каррировать функцию.Но вы сказали, что вы не можете изменить constant, поэтому у вас нет большого выбора, и вам нужно карри это как раз вовремя, например:

const curriedFunction = () => constant(someGlobalValue)();

Это создает и выбрасываетфункционировать каждый раз, когда вы вызываете его, но если вы не можете изменить constant, у вас нет большого выбора.К счастью, движки JavaScript очень быстро .

Live Copy:

const constant = v => () => v;

let someGlobalValue;

const curriedFunction = () => constant(someGlobalValue)();

someGlobalValue = 123;
console.log(curriedFunction());
...