JavaScript偏函數與函數柯里化

引子

偏函數函數柯里化是JS函數式編程中的兩個重要概念,單獨看這兩個概念,能夠輕鬆的理解,可是把這兩個概念放到一塊兒,就糊塗了,搞不清楚二者的區別與聯繫。編程

我也是第一次嘗試弄清楚二者,若有錯誤,歡迎拍磚。bash

從一個數學概念函數開始。函數式編程

函數

對於集合A中的任意元素(假設爲x),在集合B中都有惟一一個元素(假設爲y),知足某種對應關係(假設爲f),則這種對應關係就叫函數,記做y=f(x),x稱做函數的參數,y稱做函數的值。函數

能夠看出,函數是徹底對應的,即集合A中的每一個元素在集合B中都有對應值。可是,若是出現不徹底對應的狀況呢?學習

偏函數

若是出現不徹底對應的狀況,好比下圖中集合A中的4,在集合B中沒有對應值ui

這種狀況下,咱們把這樣的對應關係就叫偏函數,集合A中可能有1個或多個元素沒有對應值(此時不是函數),也有可能有0個元素沒有對應值(此時是函數),因此說spa

偏函數不都是函數,但函數都是偏函數code

多個參數的函數/偏函數

函數的參數能夠有多個,假設記做g=f(x,y) ,參數能夠看作一個有序對(x,y)的集合cdn

用JS代碼表述一下這個對應關係blog

function fn(x, y) {
  if (x === 1 && y === 1) {
    return 'a';
  } else if (x === 1 && y === 2) {
    return 'a';
  } else if (x === 2 && y === 1) {
    return 'b';
  } else if (x === 2 && y === 2) {
    return 'c';
  }
}
複製代碼

第一,不要嫌哥的代碼Low;
第二,先不要把關鍵字function叫作函數,暫且叫作對應關係

毫無疑問,對應關係fn知足函數的概念,fn是函數無疑。

同理,偏函數的參數也能夠有多個

用JS代碼表述一下這個對應關係

function partial(x, y) {
  if (x === 1 && y === 1) {
    return 'a';
  } else if (x === 1 && y === 2) {
    return 'a';
  } else if (x === 2 && y === 1) {
    return 'b';
  }
}
複製代碼

集合A中的有序對(2,2)沒有對應值,因此對應關係partial是個偏函數。

看到了麼,偏函數不是其餘文章說的什麼固定了函數的某一個或幾個參數!,我參數數量不變仍能夠是偏函數。固然,若是咱們固定其中某一個或幾個參數,好比固定x就是1,對應關係fn確定是偏函數

function fn(x, y) {
  x = 1;
  if (x === 1 && y === 1) {
    return 'a';
  } else if (x === 1 && y === 2) {
    return 'a';
  } else if (x === 2 && y === 1) {
    return 'b';
  } else if (x === 2 && y === 2) {
    return 'c';
  }
}
複製代碼

由於它只能描述部分對應關係(固然,若是集合A中把2開頭的有序對去掉,天然也是函數)

再看偏函數

到這裏就應該清楚了,若是咱們把函數的某一個或某幾個參數固定,天然只能描述部分對應關係了(也有可能還是所有描述,好比上面集合A中的x固定爲1但把以2開頭的有序對去掉),這是一個充分沒必要要條件,因此固定參數的行爲,是偏函數的一個應用。

到這裏還沒明白偏函數的,找個隱蔽的地方,本身打本身屁屁吧!

下面看函數柯里化。

函數柯里化

單獨理解函數柯里化也很簡單

把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,而且返回接受餘下的參數並且返回結果的新函數的技術。

上代碼,有一個求和函數

function sum (x, y, z) {
  return x + y + z;
}

sum(1, 2, 3); // 6
複製代碼

使用lodash的柯里化方法

const curriedSum = _.curry(sum);

curriedSum(1)(2)(3); // 6
複製代碼

柯里化有2個要求

  • 匿名函數
  • 函數只能接受一個參數

但在JS實際應用中,不少時候都不會嚴格遵照,請看lodash的柯里化方法,柯里化後容許接受多個參數

curriedSum(1, 2)(3); // 6
複製代碼

到這裏還沒明白函數柯里化的,找個隱蔽的地方,本身打本身屁屁吧!

偏函數和函數柯里化的關聯

1、這是兩個不一樣的概念,偏函數表達的是定義域和值域可能不徹底對應;函數柯里化指的是多參函數變換成單參函數的過程。

2、函數柯里化後,在調用的過程當中,出現了偏函數,仍是以上面求和函數爲例

function sum (x, y, z) {
  return x + y + z;
}

const addOne = _.curry(sum);
const addTwo = addOne(1);
const addThree = addTwo(2);
const res = addThree(3);
複製代碼
  • 函數sum柯里化後的函數爲addOne
  • addTwo是固定x爲1的偏函數
  • addThree是固定x爲1和y爲2的偏函數

最後

再次聲明:這是我第一次嘗試理清楚偏函數與函數柯里化的概念,不免出現錯誤,歡迎拍磚。

歡迎關注咱的微博,學習交流有個伴兒:@狂刀二

到這裏還沒關注咱微博的,找個隱蔽的地方,本身打本身屁屁吧!

相關文章
相關標籤/搜索