什么是函数式编程,函数合并与柯里化又是什么意思?
函數式編程在耳邊回響了多年,今天就來詳細了解一下它吧。
函數式編程的主要特征是:函數是一等公民。它建議大家寫純函數、沒有副作用的函數。
討論完純函數的內容,我們會看一下最重要的應用:函數的柯里化。
純函數的概念
純函數是這樣一種函數,即相同的輸入,永遠會得到相同的輸出,而且沒有任何可觀察的副作用。其中的副作用指的是:跟函數外部環境發生的交互。包括但不限于:
- 更改文件系統
- 往數據庫插入記錄
- 發送一個 http 請求
- 可變數據
- 打印/log
- 獲取用戶輸入
- DOM 查詢
- 訪問系統狀態
例如:slice是純函數而splice不是。
純函數的作用
可緩存性
var memoize = function(f) {var cache = {};return function() {var arg_str = JSON.stringify(arguments);cache[arg_str] = cache[arg_str] || f.apply(f, arguments);return cache[arg_str];}; };var squareNumber = memoize(function(x){ return x*x; }); squareNumber(4); //=> 16 squareNumber(4); // 從緩存中讀取輸入值為 4 的結果 //=> 16值得注意的一點是,可以通過延遲執行的方式把不純的函數轉換為純函數:
var pureHttpCall = memoize(function(url, params){return function() { return $.getJSON(url, params); } });可移植性/自文檔化
純函數對于依賴很誠實,這樣就能知道它的目的。可以說是把所有需要的(可變的)參數都傳遞進來。
可測試性
簡單地給函數一個輸入,就能有輸出了。
合理性
如果一段代碼可以替換成它執行所得的結果,而且是在不改變整個程序行為的前提下替換的,那么我們就說這段代碼是引用透明的。這樣會對理解代碼非常重要,因為“可以使用等式推導”(equational reasoning)的技術來分析代碼,就是“一對一”替換的情況下手動執行代碼。
并行代碼
最后一點,也是決定性的一點:我們可以并行運行任意純函數。因為純函數根本不需要訪問共享的內存,而且根據其定義,純函數也不會因副作用而進入競爭態(race condition)。
并行代碼在服務端 js 環境以及使用了 web worker 的瀏覽器那里是非常容易實現的,因為它們使用了線程(thread)。不過出于對非純函數復雜度的考慮,當前主流觀點還是避免使用這種并行。
合并
合并就是一個值經過多個函數變化最后輸出結果。很明顯是一個 reduce 的概念。
比如 a(b(c(d))) 看起來很不舒服,很像 JS 里的回調地域有特別多的大括號。所以我們要是有一個 compose 函數,可以將表達式寫成 [c, b, a].compose(d) 該多好,而且如果數組里的函數都是純函數,甚至還能滿足結合律。
function compose(array) {return function(args) {return array.reduce(function (total, f) {return f(total);}, args);} }或者
function compose(array) {return function(args) {let result = args;array.forEach(function(f) {result = f(result);});return result;} }柯里化
curry 的概念很簡單:只傳遞給函數一部分參數來調用它,讓它返回一個函數去處理剩下的參數。
function curry(fn) {return function finalCurry(...args) {if (args.length >= fn.length) {return fn(...args);} else {return function (...args2) {return finalCurry(...args, ...args2);}}} }總結
以上是生活随笔為你收集整理的什么是函数式编程,函数合并与柯里化又是什么意思?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (附源码)计算机毕业设计ssm关山社区居
- 下一篇: 大数据之Sqoop 二