为什么从 reducing/composing 提取时我的传感器不再工作?
Why doesn't my transducer work anymore when abstracting from reducing/composing?
我对短路和堆栈安全传感器实施感到困惑:
const loop = f => {
let acc = f();
while (acc && acc.type === tailRec)
acc = f(...acc.args);
return acc;
};
const tailRec = (...args) =>
({type: tailRec, args});
const arrFoldk = f => acc_ => xs =>
loop((acc = acc_, i = 0) =>
i === xs.length
? acc
: f(acc) (xs[i]) (acc_ => tailRec(acc_, i + 1)));
const liftk2 = f => x => y => k =>
k(f(x) (y));
const isOdd = n => n & 1 === 1;
const concat = xs => ys => xs.concat(ys);
const comp = f => g => x => f(g(x));
const id = x => x;
const filterReduce = filter => reduce => acc => x => k =>
filter(x)
? reduce(acc) (x) (k)
: k(acc);
const takeReduce = n => reduce => acc => x => k =>
acc.length === n
? reduce(acc) (x) (id)
: reduce(acc) (x) (k);
const fx = filterReduce(isOdd),
fy = takeReduce(3),
fz = comp(fy) (fx);
const transducek = (...fs) => xs =>
arrFoldk(fs.reduce((f, g) => comp(f) (g), id) (liftk2(concat))) ([]);
const r1 = arrFoldk(fz(liftk2(concat))) ([]) ([1,2,3,4,5,6,7,8,9]);
const r2 = transducek(fx, fy) ([1,2,3,4,5,6,7,8,9]);
console.log(r1); // [1,3,5]
console.log(r2); // xs => ...
我正在查看代码,它非常清楚地告诉我,分别产生 r1
和 r2
的计算本质上是相同的。为什么在应用 transduce
辅助函数时我得不到相同的结果?
不确定这些是否是您要查找的错误,但以下两点让我印象深刻:
您已将 xs
包含在 transduceK
的签名中,但从未使用此参数调用组合函数。要么在最后添加 (xs)
,要么只做:
const transducek = (...fs) =>
arrFoldk(fs.reduce((f, g) => comp(f) (g), id) (liftk2(concat))) ([]);
等同于comp (fy) (fx)
[fx, fy].reduceRight((g, h) => comp (g) (h), id)
或[fx, fy].reduce((f, g) => comp(g) (f), id)
经过这些更改,我认为一切都按预期进行:
const loop = f => {
let acc = f();
while (acc && acc.type === tailRec)
acc = f(...acc.args);
return acc;
};
const tailRec = (...args) =>
({type: tailRec, args});
const arrFoldk = f => acc_ => xs =>
loop((acc = acc_, i = 0) =>
i === xs.length
? acc
: f(acc) (xs[i]) (acc_ => tailRec(acc_, i + 1)));
const liftk2 = f => x => y => k =>
k(f(x) (y));
const isOdd = n => n & 1 === 1;
const concat = xs => ys => xs.concat(ys);
const comp = f => g => x => f(g(x));
const id = x => x;
const filterReduce = filter => reduce => acc => x => k =>
filter(x)
? reduce(acc) (x) (k)
: k(acc);
const takeReduce = n => reduce => acc => x => k =>
acc.length === n
? reduce(acc) (x) (id)
: reduce(acc) (x) (k);
const fx = filterReduce(isOdd),
fy = takeReduce(3),
fz = comp(fy) (fx);
const transducek = (...fs) =>
arrFoldk(fs.reduce((f, g) => comp(g) (f), id) (liftk2(concat))) ([]);
const r1 = arrFoldk(fz(liftk2(concat))) ([]) ([1,2,3,4,5,6,7,8,9]);
const r2 = transducek(fx, fy) ([1,2,3,4,5,6,7,8,9]);
console.log(r1); // [1,3,5]
console.log(r2); // [1,3,5]
我对短路和堆栈安全传感器实施感到困惑:
const loop = f => {
let acc = f();
while (acc && acc.type === tailRec)
acc = f(...acc.args);
return acc;
};
const tailRec = (...args) =>
({type: tailRec, args});
const arrFoldk = f => acc_ => xs =>
loop((acc = acc_, i = 0) =>
i === xs.length
? acc
: f(acc) (xs[i]) (acc_ => tailRec(acc_, i + 1)));
const liftk2 = f => x => y => k =>
k(f(x) (y));
const isOdd = n => n & 1 === 1;
const concat = xs => ys => xs.concat(ys);
const comp = f => g => x => f(g(x));
const id = x => x;
const filterReduce = filter => reduce => acc => x => k =>
filter(x)
? reduce(acc) (x) (k)
: k(acc);
const takeReduce = n => reduce => acc => x => k =>
acc.length === n
? reduce(acc) (x) (id)
: reduce(acc) (x) (k);
const fx = filterReduce(isOdd),
fy = takeReduce(3),
fz = comp(fy) (fx);
const transducek = (...fs) => xs =>
arrFoldk(fs.reduce((f, g) => comp(f) (g), id) (liftk2(concat))) ([]);
const r1 = arrFoldk(fz(liftk2(concat))) ([]) ([1,2,3,4,5,6,7,8,9]);
const r2 = transducek(fx, fy) ([1,2,3,4,5,6,7,8,9]);
console.log(r1); // [1,3,5]
console.log(r2); // xs => ...
我正在查看代码,它非常清楚地告诉我,分别产生 r1
和 r2
的计算本质上是相同的。为什么在应用 transduce
辅助函数时我得不到相同的结果?
不确定这些是否是您要查找的错误,但以下两点让我印象深刻:
您已将
xs
包含在transduceK
的签名中,但从未使用此参数调用组合函数。要么在最后添加(xs)
,要么只做:const transducek = (...fs) => arrFoldk(fs.reduce((f, g) => comp(f) (g), id) (liftk2(concat))) ([]);
等同于
comp (fy) (fx)
[fx, fy].reduceRight((g, h) => comp (g) (h), id)
或[fx, fy].reduce((f, g) => comp(g) (f), id)
经过这些更改,我认为一切都按预期进行:
const loop = f => {
let acc = f();
while (acc && acc.type === tailRec)
acc = f(...acc.args);
return acc;
};
const tailRec = (...args) =>
({type: tailRec, args});
const arrFoldk = f => acc_ => xs =>
loop((acc = acc_, i = 0) =>
i === xs.length
? acc
: f(acc) (xs[i]) (acc_ => tailRec(acc_, i + 1)));
const liftk2 = f => x => y => k =>
k(f(x) (y));
const isOdd = n => n & 1 === 1;
const concat = xs => ys => xs.concat(ys);
const comp = f => g => x => f(g(x));
const id = x => x;
const filterReduce = filter => reduce => acc => x => k =>
filter(x)
? reduce(acc) (x) (k)
: k(acc);
const takeReduce = n => reduce => acc => x => k =>
acc.length === n
? reduce(acc) (x) (id)
: reduce(acc) (x) (k);
const fx = filterReduce(isOdd),
fy = takeReduce(3),
fz = comp(fy) (fx);
const transducek = (...fs) =>
arrFoldk(fs.reduce((f, g) => comp(g) (f), id) (liftk2(concat))) ([]);
const r1 = arrFoldk(fz(liftk2(concat))) ([]) ([1,2,3,4,5,6,7,8,9]);
const r2 = transducek(fx, fy) ([1,2,3,4,5,6,7,8,9]);
console.log(r1); // [1,3,5]
console.log(r2); // [1,3,5]