摘要:在函數式編程語言中,這一特性可用于構造無限列表。學習網址,是一個擁有和函數的數據類型,類似于,但它會輸出非嵌套形式的結果在其他函數式編程語言中,也被稱為,也被稱為和。
原文連接
[TOC]
Arity指函數的參數數量,由 -ary 和 -ity 這兩個英文后綴拼接而成:
const sum = (a, b) => a + b; const Arity = sum.length; console.log(Arity); // 輸出結果為 2Higher-Order Functions
高階函數,此類函數可以接收其他函數作為參數,也可以返回一個函數作為返回值:
const filter = (predFunc, list) => { const results = []; list.forEach((listItem) => { if (predFunc(listItem)) { results.push(listItem); } }); return results; } // filter 這個函數就是將一個函數作為參數傳入 // 但這都么有什么,主要是后面is函數返回一個函數 const is = (type) => (x) => Object(x) instanceof type; // is這個函數就是將一個函數作為返回值返回到下面的調用之中 filter(is(Number), [0, "1", 2, null]); // 上面函數調用的結果是 [0, 2]Partial Application
偏函數,在原函數的基礎上預填充(pre-filling)部分參數并返回的新函數:
// 下面是一個創建偏函數的輔助函數,下面函數將一個函數和這個函數所需要的除了最后一個參數的參數傳入,返回一個新的函數,這個新的函數的參數為原函數的最后一個參數 const partial = (func, ...args) => (...moreArgs) => func(...args, ...moreArgs); // 寫一個將三個數字相加的函數 const add3 = (a, b, c) => a + b + c; // 預填充 (add3, 2, 3) 三個參數,空置最后一個參數,返回一個新的函數,重點是返回一個新的函數 const fivePlus = partial(add3, 2, 3); // (c) => 2 + 3 + c fivePlus(4); // => 9Currying
柯里化,將一個接收多個參數的函數轉化為單參數函數的方式,轉化后的函數每次只接收一個參數,然后返回一個新函數,新函數可以繼續接收參數,直到接收到所有的參數:
const sum = (a, b) => a + b; sum(2, 3); // => 6 const curriedSum = (a) => (b) => a + b; curriedSum(40)(2); // => 42. const add2 = curriedSum(2); // (b) => 2 + b add2(10); // => 12Function Composition
函數合成,接收多個函數作為參數并返回一個新函數的方式,新函數按照傳入的參數順序,從右往左依次執行,前一個函數的返回值是后一個函數的輸入值:
const compose = (f, g) => (a) => f(g(a)); const floorAndToString = compose((val) => val.toString(), Math.floor); floorAndToString(121.212121); // => "121"Purity
一個純函數需要滿足兩個條件,第一是函數的返回值只能由輸入值(函數接收的參數)決定,也就是說純函數接收相同的參數會返回相同的值;第二是純函數不會對自身作用域之外的運行環境產生副作用(side effects),比如說不會改變外部環境中變量的值,這會被認為是不安全的行為:
純函數示例:
const greet = (name) => "Hi, " + name ; greet("Brianne") // => "Hi, Brianne"Side effects
如果函數或表達式與其自身作用域之外的可變數據(mutable data)發生了讀寫操作,那么此時函數和表達式就產生了副作用:
let greeting; const greet = () => greeting = "Hi, " + window.name; // greet() 執行時更改了外部環境的變量 greet(); // => "Hi, Brianne" // new Date() 是可變數據 const differentEveryTime = new Date();Point-Free Style
point-free style 是一種不顯式向函數傳遞參數的代碼風格,通常需要柯里化和高階函數來實現:
const map = (fn) => (list) => list.map(fn); const add = (a) => (b) => a + b; // Not points-free // numbers 是一個顯式傳遞的參數 const incrementAll = (numbers) => map(add(1))(numbers); // Points-free // add(1) 的返回值隱式傳遞給了 map,作為 map 的 list 參數 const incrementAll2 = map(add(1));Predicate
斷言,一個返回布爾值的函數:
const predicate = (a) => a > 2; [1, 2, 3, 4].filter(predicate); // => [3, 4]Constant
常量,初始化后不能再次執行賦值操作的數據類型:
const five = 5; const john = { name: "John", age: 30 }; // 因為常量不可變,所以下面表達式一定為 true john.age + five === ({ name: "John", age: 30 }).age + (5);
常量具有 referentially transparent 的特性,也就是說將程序中出現的常量替換為它們實際的值,并不會影響程序的結果。譯者話外:實際上在 JavaScript 中的 const 所聲明的常量并不是完全穩定的,使用 Immutable.js 演示更加恰當:
// 這里的fromJS(), get()函數都是immutable.js所提供的方法 const five = fromJS(5); const john = fromJS({name: "John", age: 30}); john.get("age") + five === ({ name: "John", age: 30 }).age + (5);Functor
functor 都擁有 map 函數,并且在執行 map 之后會返回一個新的 functor:
object.map(x => x) === object; object.map(x => f(g(x))) === object.map(g).map(f);
JavaScript 中最常見的 functor 就是數組類型的實例:
[1, 2, 3].map(x => x); // => [1, 2, 3] const f = x => x + 1; const g = x => x * 2; [1, 2, 3].map(x => f(g(x))); // => [3, 5, 7] [1, 2, 3].map(g).map(f); // => [3, 5, 7]Lift
lift 發生在你將值放入 functor 的時候,如果你將函數 lift 進了 Applicative Functor,那么就可以使用這個函數處理傳遞給這個 functor 的值。某些 lift 的實現擁有 lift 或 liftA2 函數,便于在 functor 上執行相關的函數:
const mult = (a, b) => a * b; const liftedMult = lift(mult); // => this function now works on functors like array liftedMult([1, 2], [3]); // => [3, 6] lift((a, b) => a + b)([1, 2], [3, 4]); // => [4, 5, 5, 6]
lift 一個單參數的函數非常類似于 map 操作:
const increment = (x) => x + 1; lift(increment)([2]); // => [3] [2].map(increment); // => [3]Lambda
匿名函數,本質上是一個 value:
function(a){ return a + 1; }; (a) => a + 1; // Lambda 常用語高階函數中 [1, 2].map((a) => a + 1); // = [2, 3] // Lambda 作為 value 被賦值給變量 let addOne = (a) => a + 1;Lazy evaluation
惰性求值,是一種按需執行的求值策略,只有需要某個值時才會執行相關的表達式。在函數式編程語言中,這一特性可用于構造無限列表。
const rand = function*() { while (true) { yield Math.random(); } } const randIter = rand(); randIter.next().value; // 每次執行 next() 函數都會返回一個新的隨機數 // 有且只有在執行 next() 的時候才會返回新值 // function* 聲明(function關鍵字后跟一個星號)定義一個generator // (生成器)函數,返回一個Generator對象。 // 學習網址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/function*Monad
Monad,是一個擁有 of 和 chain 函數的數據類型,chain 類似于 map,但它會輸出非嵌套形式的結果:
["cat,dog", "fish,bird"].chain((a) => a.split(",")) // => ["cat", "dog", "fish", "bird"] ["cat,dog", "fish,bird"].map((a) => a.split(",")) // => [["cat", "dog"], ["fish", "bird"]]
在其他函數式編程語言中,of 也被稱為 return,chain 也被稱為 flatmap 和 bind。
Isomorphism同構轉換,相同數據下不同結構之間的轉換。舉例來說,2D 坐標既可以存儲為數組 [2, 3] 也可以存儲為 { x: 2, y: 3 }:
const pairToCoords = (pair) => ({x: pair[0], y: pair[1]}) const coordsToPair = (coords) => [coords.x, coords.y] coordsToPair(pairToCoords([1, 2])) // => [1, 2] pairToCoords(coordsToPair({x: 1, y: 2})) // => { x: 1, y: 2 }Setoid
Setoid,擁有 equals 函數的數據類型,可用于與其他同類型的數據進行比較。為 Array 類型添加 equals 函數使其成為 Setoid:
Array.prototype.equals = (arr) => { const len = this.length if (len !== arr.length) { return false } for (let i = 0; i < len; i++) { if (this[i] !== arr[i]) { return false } } return true } [1, 2].equals([1, 2]) // => true [1, 2].equals([0]) // => falseSemigroup
Semigroup,擁有 concat 函數的數據類型,可以與同類型數據進行合并:
[1].concat([2]) // => [1, 2]Foldable
Foldable,擁有 reduce 函數的數據類型,可以將 Foldable 的實例轉換為其他數據類型:
const sum = (list) => list.reduce((acc, val) => acc + val, 0); sum([1, 2, 3]) // => 6
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/80714.html
摘要:所以我覺得函數式編程領域更像學者的領域。函數式編程的原則是完善的,經過了深入的研究和審查,并且可以被驗證。函數式編程是編寫可讀代碼的最有效工具之一可能還有其他。我知道很多函數式編程編程者會認為形式主義本身有助于學習。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson - 《You-Dont-Know-JS》作者 關于譯者:這是一個流淌著滬江血液...
摘要:函數式編程術語大全函數式編程有許多優點,它也越來越流行了。然而,每個編程范式都有自己獨特的術語,函數式編程也不例外。作用域有兩種類似全局作用域和局部作用域。目前最重要的應用場景之一,就是在的握手階段,客戶端服務端利用算法交換對稱密鑰。 1、JavaScript 函數式編程術語大全 函數式編程(FP)有許多優點,它也越來越流行了。然而,每個編程范式都有自己獨特的術語,函數式編程也不例外。...
摘要:函數式編程術語大全函數式編程有許多優點,它也越來越流行了。然而,每個編程范式都有自己獨特的術語,函數式編程也不例外。作用域有兩種類似全局作用域和局部作用域。目前最重要的應用場景之一,就是在的握手階段,客戶端服務端利用算法交換對稱密鑰。 1、JavaScript 函數式編程術語大全 函數式編程(FP)有許多優點,它也越來越流行了。然而,每個編程范式都有自己獨特的術語,函數式編程也不例外。...
摘要:而純函數,主要強調相同的輸入,多次調用,輸出也相同且無副作用。對于組合可能不返回值的函數很有用在其它的一些地方,也稱為,也稱為,也稱為 參考文檔1 參考文檔2 函數式編程術語 高階函數 Higher-Order Functions 以函數為參數的函數 返回一個函數的函數 函數的元 Arity 比如,一個帶有兩個參數的函數被稱為二元函數 惰性求值 Lazy evaluation 是...
摘要:從某些方面來講,這章回顧的函數知識并不是針對函數式編程者,非函數式編程者同樣需要了解。什么是函數針對函數式編程,很自然而然的我會想到從函數開始。如果你計劃使用函數式編程,你應該盡可能多地使用函數,而不是程序。指的是一個函數聲明的形參數量。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson - 《You-Dont-Know-JS》作者 關于譯者:...
閱讀 785·2023-04-26 00:30
閱讀 2689·2021-11-23 09:51
閱讀 1045·2021-11-02 14:38
閱讀 2560·2021-09-07 10:23
閱讀 2243·2021-08-21 14:09
閱讀 1362·2019-08-30 10:57
閱讀 1603·2019-08-29 11:20
閱讀 1149·2019-08-26 13:53