![](/img/trans.png)
[英]The Hapijs Glue 'compose' function should not work, but it does. How?
[英]How does compose function work with multiple parameters?
這是我需要改進的“撰寫”功能:
const compose = (fns) => (...args) => fns.reduceRight((args, fn) => [fn(...args)], args)[0];
這是一個的實際實現:
const compose = (fns) => (...args) => fns.reduceRight((args, fn) => [fn(...args)], args)[0]; const fn = compose([ (x) => x - 8, (x) => x ** 2, (x, y) => (y > 0 ? x + 3 : x - 3), ]); console.log(fn("3", 1)); // 1081 console.log(fn("3", -1)); // -8
這是我的導師提出的改進。
const compose = (fns) => (arg, ...restArgs) => fns.reduceRight((acc, func) => func(acc, ...restArgs), arg);
如果我們在第一次迭代時傳遞像 func(x, [y]) 這樣的參數列表,我仍然不明白我們如何使函數與 [y] 的解壓縮數組一起工作?
compose
做了什么compose = (fns) =>
(arg, ...restArgs) =>
fns.reduceRight((acc, func) => func(acc, ...restArgs), arg);
當您使用許多函數輸入compose
時,您會返回……一個函數。 在你的情況下,你給它一個名字, fn
。
這個fn
函數是什么樣的? 通過簡單的替換,您可以將其視為這樣:
(arg, ...restArgs) => fns.reduceRight((acc, func) => func(acc, ...restArgs), arg);
其中fns === [(x) => x - 8, (x) => x ** 2, (x, y) => (y > 0 ? x + 3 : x - 3)]
。
所以你可以給這個函數fn
提供一些參數,這些參數將與(arg, ...restArgs)
進行“模式匹配”; 在您的示例中,當您調用fn("3", 1)
, arg
為"3"
而restArgs
為[1]
(因此...restArgs
在逗號后擴展為1
,因此您會看到fn("3", 1)
減少到
fns.reduceRight((acc, func) => func(acc, 1), "3");
由此你看到
(x, y) => (y > 0 ? x + 3 : x - 3)
使用兩個參數"3"
( acc
的初始值)和1
調用,func
, 但關鍵是func
的第二個參數,即1
,只被最右邊的函數使用,而它被傳遞給其他兩個函數但被忽略!
函數組合是介於一元函數之間的東西。 將它與具有高於 1 元數的函數一起使用會導致混淆。
例如考慮這兩個函數
square = (x) => x**2; // unary
plus = (x,y) => x + y; // binary
你能編曲嗎? 好吧,你可以將它們組合成這樣的函數
sum_and_square = (x,y) => square(plus(x,y));
您在問題底部的compose
功能會很順利:
sum_and_square = compose([square, plus]);
但是如果你的兩個函數是這些呢?
apply_twice = (f) => ((x) => f(f(x))); // still unary, technically
plus = (x,y) => x + y; // still binary
您的compose
將不起作用。
即使,如果函數plus
被柯里化,例如,如果它被定義為
plus = (x) => (y) => x + y
那么人們可以考慮將它們組合在一個函數中,其作用如下:
f = (x,y) => apply_twice(plus(x))(y)
這將可預見地產生result(3,4) === 10
。
您可以將其設為f = compose([apply_twice, plus])
。
此外,我建議進行“裝飾性”更改:使compose
接受...fns
而不是fns
,
compose = (...fns)/* I've only added the three dots on this line */ =>
(arg, ...restArgs) =>
fns.reduceRight((acc, func) => func(acc, ...restArgs), arg);
並且您將能夠在沒有 groupint 的情況下調用它以將要組合在數組中的函數,例如,您將編寫compose(apply_twice, plus)
而不是 。compose([apply_twice, plus])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.