Это новая тема, связанная с этой темой. Пожалуйста, просмотрите, спасибо!
ложная тема моего предыдущего вопроса здесь:
Как хранить данные функциональной цепочки?
Краткая идея
Простая функция ниже:
const L = a => L;
формы
L
L(1)
L(1)(2)
...
Кажется, что это формирует список, но фактические данные не хранятся вообще, поэтому, если требуется хранить такие данные, как [1,2], какова самая разумная практика для выполнения задачи?
Одна из выдающихся идей принадлежит @ user633183, который я пометил как принятый ответ (см. Ссылку «Вопрос»), а @ Matías Fidemraizer также предоставляет другую версию функции с карри.
Так что здесь идет:
const L = a => {
const m = list => x => !x
? list
: m([...list, x]);
return m([])(a);
};
const list1 = (L)(1)(2)(3); //lazy : no data evaluation here
const list2 = (L)(4)(5)(6);
console.log(list1()) // now evaluated by the tail ()
console.log(list2())
Что мне действительно нравится, так это ленивая оценка.
Хотя данный подход удовлетворяет тому, что я упомянул, эта функция утратила внешнюю структуру, или я должен упомянуть:
Алгебраическая структура const L = a => L;
который формирует список и более фундаментально дает намалгебраическая структура изэлемент идентичностипотенциально вместе сMonoid или жемагма.
Оставил право личностиОдним из самых простых примеров моноидов и идентичности является число и"Strings"
а также[Array]
в JavaScript.
0 + a === a === a + 0
1 * a === a === a * 1
В строках пустое значение""
это элемент идентичности.
"" + "Hello world" === "Hello world" === "Hello world" + ""
То же самое относится и к[Array]
.
То же самое относится и кL
:
(L)(a) === (a) === (a)(L)
const L = a => L;
const a = L(5); // number is wrapped or "lift" to Type:L
// Similarity of String and Array
// "5" [5]
//left identity
console.log(
(L)(a) === (a) //true
);
//right identity
console.log(
(a) === (a)(L) //true
);
и очевидная идентичность неизменности:
const L = a => L;
console.log(
(L)(L) === (L) //true
);
console.log(
(L)(L)(L) === (L) //true
);
console.log(
(L)(L)(L)(L) === (L) //true
);
Также ниже:
const L = a => L;
const a = (L)(1)(2)(3);
const b = (L)(1)(L)(2)(3)(L);
console.log(
(a) === (b) //true
);
ВопросовКакой самый умный или самый элегантный способ (очень функциональный и без мутаций (нетArray.push
также)) реализоватьL
это удовлетворяет 3 требованиям:
Простая функция:
const L = a => L;
уже удовлетворяет закону идентичности, как мы уже видели.
Требование 1 - метод eval ()Несмотря на то чтоL
удовлетворяет закону об идентичности, нет способа доступа к перечисленным / накопленным данным.
(Ответы, представленные в моем предыдущем вопросе, обеспечивают возможность накопления данных, но нарушают закон об идентификации.)
Ленивая оценка кажется правильным подходом, поэтому предоставление более четкой спецификации:
предоставлятьeval
методL
const L = a => L; // needs to enhance to satisfy the requirements
const a = (L)(1)(2)(3);
const b = (L)(1)(L)(2)(3)(L);
console.log(
(a) === (b) //true
);
console.log(
(a).eval() //[1, 2, 3]
);
console.log(
(b).eval() //[1, 2, 3]
);
Требование 3 - Моноид Ассоциативное правоВ дополнение к выдающейся структуре идентификации, моноиды также удовлетворяютАссоциативный закон
(a * b) * c === a * b * c === a * (b * c)
Это просто означает «сгладить список», другими словами, структура не содержит вложенных списков.
[a, [b, c]]
не хорошо
Образец:
const L = a => L; // needs to enhance to satisfy the requirements
const a = (L)(1)(2);
const b = (L)(3)(4);
const c = (L)(99);
const ab = (a)(b);
const bc = (b)(c);
const abc1 = (ab)(c);
const abc2 = (a)(bc);
console.log(
abc1 === abc2 // true for Associative
);
console.log(
(ab).eval() //[1, 2, 3, 4]
);
console.log(
(abc1).eval() //[1, 2, 3, 4, 99]
);
console.log(
(abc2).eval() //[1, 2, 3, 4, 99]
);
Это все для 3 требований для реализацииL
как моноид
Для меня это сложная задача для функционального программирования, и на самом деле я некоторое время пытался сам, но задавая предыдущие вопросы, очень полезно делиться своими собственными задачами, слышать людей и читать их элегантный код.
Спасибо.