簡體   English   中英

檢查咖喱 function 是否仍然期待進一步的 arguments

[英]Check if a curried function is still expecting further arguments

I would like to know if it possible to find out how many remaining arguments a curried function is expecting in javascript, if possible, without ever actually calling the function. 我想要一個 function ,它需要一個 function 並在 function 期望剩余 2 個或更多 ZDBC1FB4DABDABDA8 時返回。

hasSeveralRemainingArguments: fn => bool

假設我有以下功能:

const double = x => 2*x;
const inc = x => x + 1;
const divideBy = ({dividor}) => x => x/dividor;
const decrementAndDivideBy = ({dividor}) => x => (x - 1)/dividor;

hasSeveralRemainingArguments(double); // false
hasSeveralRemainingArguments(inc); // false
hasSeveralRemainingArguments(divideBy); // true
hasSeveralRemainingArguments(divideBy({dividor: 5})); // false
hasSeveralRemainingArguments(decrementAndDivideBy); // true
hasSeveralRemainingArguments(decrementAndDivideBy({dividor: 5})); // false

用例是 function foo ,它需要一個選項參數和一個要調用的函數數組。 我想通過函數數組“ pipe ”並將選項參數僅輸入到實際期望參數的函數,例如在這種情況下divideBydecrementAndDivideBy ,例如:

const pipe = (...fns) => x => fns.reduce((y, fn) => fn(y), x);

const foo = (options = {}) => (fns = []) => pipe(
  fns.map(fn => (
    hasSeveralRemainingArguments(fn) ? 
      fn(options) : 
      fn
  )
);

const bar = (...fns) => {
  const options = {
    dividor: 3
  }; // local, not known to the caller of bar. They just know that they can pass in a function which will receive an options-object, they just don't know what is inside this object.

  return foo(options)(fns);
});

const baz = bar(
  double,
  inc, 
  divideBy,
  decrementAndDivideBy
);

baz(4); // ((4*2 + 1)/3 - 1)/3 = 0.67
baz(10); // ((10*2 + 1)/3 - 1)/3 = 2

function bar的調用者不知道options參數。 否則我可以在將函數傳遞給bar之前輸入options參數,但不幸的是這是不可能的。

您還應該注意, doubleincdivideBydecrementAndDivideBy被構建為只接受數字作為參數x但這可能並非總是如此。 如果可能的話,我不想調用函數並測試返回的值是否是 function 但目前我沒有看到任何其他方式。

我也可以使用 function 和 boolean "isExpectingOptions" 傳遞對象,但這對於調用bar的人來說不是很好/優雅。

你有別的想法嗎?

您是否考慮過使用 function 的length屬性?

length 屬性表示 function 期望的參數數量。

const a = curry((x, y, z) => 42);

a.length       // 3
a(1).length    // 2
a(1)(2).length // 1

正如已經指出的,您可以檢查 function 的數量,但是如果手動實現柯里化,這實際上不起作用。

 const nSum = R.curry((a, b, c) => { console.log('nSum.length', nSum.length); return a + b + c; }); const uSum = (a) => (b) => (c) => { console.log('uSum.length', uSum.length); return a + b + c; }; nSum(1, 2, 3); uSum(1)(2)(3);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js" integrity="sha256-buL0byPvI/XRDFscnSc/e0q+sLA65O9y+rbF+0O/4FE=" crossorigin="anonymous"></script>


您可能會構建一個getArity function,但這需要應用 function 來提取其 arguments 的數量...

 const getArity = (fn, arg) => { const res = fn(arg); return 1 + ( typeof res === 'function'? getArity(res, arg): 0 ); }; const uSum = (a) => (b) => (c) => a + b + c; console.log( getArity(uSum, 0), ); const sum2 = uSum(0); console.log( getArity(sum2, 0), );

這個 function 也並沒有真正告訴你 function 的數量……但是如果我們假設它是一元的,可以計算多少時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM