我已阅读有关换能器的网络文章
s
从一半很难理解...
Clojure
我阅读了大约2页的Clojure官方教程,并了解了基本语法。我引用了内置函数引用以了解传感器示例代码。
我对以上两篇文章的理解可能是75%...
我的问题
我想知道以下理解/ js代码是否正确。请帮助我。
关于换能器
compose()
返回的值是一个转换器。 transduce()
函数作为参数来执行,此外,(2)Transducer通过将数组直接传递给transducer()
来执行。 我的代码
"use strict";
const map = fn => arr => arr.map(fn),
filter = fn => arr => arr.filter(fn),
addReducer = arr => arr.reduce((acc, num) => acc + num, 0),
add1 = n => n + 1,
even = n => n % 2 === 0,
compose = (...fns) => initVal => fns.reduce((acc, fn) => fn(acc), initVal),
transduce = (xform, reducer, arr ) => reducer( xform(arr) );
const arr = [1,2,3],
transducer = compose( /* called transducer or xform */
map( add1 ), // 2,3,4
filter( even ), // 2,4
);
console.log( transducer(arr) ) // 2,4
console.log( transduce(transducer, addReducer, arr) ) // 6
最佳答案
换能器利用了这样的事实,即函数组成从arity中抽象出来,即可以返回一个函数而不是“正常值”:
const comp = f => g => x => f(g(x));
const add = x => y => x + y;
const sqr = x => x * x;
const add9 = comp(add) (sqr) (3); // returns a lambda
console.log(
add9(6)); // 15
现在换能器本身很无聊:
reduce => acc => x => /* body is specific to the transducer at hand */
它只是一个期望使用reducer的闭包(即结合了两个参数的二进制函数),然后可以直接将其馈送到您喜欢的reduce函数中。
让我们看一下 map 转换器:
const mapper = f => (reduce => acc => x =>
reduce(acc) (f(x)));
多余的括号仅说明了传感器的闭合情况。在这种情况下,它将关闭我们的转换函数
f
。接下来,我们将应用它:// map transducer
const mapper = f => reduce => acc => x =>
reduce(acc) (f(x));
// my favorite fold (reducing function)
const arrFold = alg => zero => xs => {
let acc = zero;
for (let i = 0; i < xs.length; i++)
acc = alg(acc) (xs[i], i);
return acc;
};
// reducer
const add = x => y => x + y;
// transformer
const sqr = x => x * x;
// MAIN
const main = arrFold(mapper(sqr) (add)) (0);
console.log(
main([1,2,3])); // 14
好吧,不是那么令人印象深刻吧?传感器的有功功率是由其与功能组成的组合得出的:
// map transducer
const mapper = f => reduce => acc => x =>
reduce(acc) (f(x));
// filter transducer
const filterer = p => reduce => acc => x =>
p(x) ? reduce(acc) (x) : acc;
// my favorite fold (reducing function)
const arrFold = alg => zero => xs => {
let acc = zero;
for (let i = 0; i < xs.length; i++)
acc = alg(acc) (xs[i], i);
return acc;
};
// helpers
const add = x => y => x + y; // reducer
const sqr = x => x * x; // transformer
const isOdd = x => (x & 1) === 1; // predicate
const comp = f => g => x => f(g(x));
// MAIN
const main = arrFold(comp(filterer(isOdd)) (mapper(sqr)) (add)) (0);
console.log(
main([1,2,3])); // 10
尽管我们涉及两个换能器,但仅通过
Array
进行一次遍历。此属性称为循环融合。由于换能器组成返回了另一个功能,因此评估顺序相反,即从左到右,而功能组成通常从右到左。可重用性是另一个优势。您只需要定义一次传感器,就可以一次全部使用所有可折叠数据类型。
还值得注意的是,
transduce
只是一个便捷函数,对于理解该概念并不重要。关于换能器,这差不多可以说了。