天天看點

讀程式設計與類型系統筆記05_函數類型

作者:躺着的柒
讀程式設計與類型系統筆記05_函數類型

讀程式設計與類型系統筆記05_函數類型

1.政策模式

1.1.在運作時從一組算法中選擇某個算法

1.1.1.封裝一組算法

1.1.2.在運作時使用其中一個算法

1.2.把算法與使用算法的元件解耦

1.3.面向對象實作

1.3.1.慣例實作

1.3.2.IStrategy接口

1.3.3.ConcreteStrategy1類

1.3.4.ConcreteStrategy2類

1.3.5.通過IStrategy接口使用算法的Context類

1.3.6.常見原因

1.3.6.1.依賴接口的方法

1.3.6.2.設計模式在20世紀90年代流行起來

1.3.6.3.當時并不是所有主流程式設計語言都支援一等函數

1.4.函數式實作

1.4.1.Context類

1.4.2.concreteStrategy1()函數

1.4.3.concreteStrategy2()函數

1.4.4.更簡潔的實作

2.函數的類型

2.1.函數的簽名

2.2.函數的實參類型和傳回類型決定了函數的類型

2.3.兩個函數接受相同的實參,并傳回相同的類型

2.3.1.函數具有相同的類型

3.一等函數

3.1.将函數指派給變量,并像處理類型系統中的其他值一樣處理它們

3.2.一等公民

3.2.1.賦予它們與其他值相同的權利

3.2.2.有類型

3.2.3.可被指派給變量

3.2.4.可作為實參傳遞

3.2.5.可被檢查是否有效

3.2.6.在相容的情況下可被轉換為其他類型

4.狀态機

4.1.有一組狀态,以及狀态之間的轉移

4.2.以給定狀态(也叫作開始狀态)開始;如果滿足特定條件,就能轉移到另外一個狀态

4.3.經典的狀态機

4.3.1.将狀态集合定義為一個枚舉

4.3.2.跟蹤目前的狀态

4.3.3.使用覆寫所有可能狀态的switch語句來獲得所希望的行為

4.3.4.使用switch語句的狀态機

4.3.4.1.缺點

4.3.4.1.1.狀态沒有與想要在每種狀态下運作的邏輯聯系在一起

4.3.4.1.2.狀态和轉移作為一個單獨的枚舉進行維護,有不同步的風險

4.4.使用函數的狀态機

4.4.1.狀态完全是由一個函數來表示

4.4.2.不需要單獨跟蹤狀态

4.4.2.1.狀态與處理邏輯保持同步

4.4.2.2.去掉了枚舉

4.4.2.3.去掉狀态屬性

4.4.2.4.去掉處理轉交給合适方法的switch語句

4.4.3.更簡潔的實作

4.4.3.1.缺點:每種狀态關聯更多資訊要顯式聲明可能的狀态和轉移

4.5.使用和類型的狀态機

4.5.1.把每種狀态表示為一個單獨的類型

4.5.2.整個狀态機表示為可能狀态的一個和類型

4.5.3.把狀态機分解到類型安全的元件中

4.5.4.比依賴函數的實作更長

4.5.4.1.優點:允許我們在每種狀态中添加屬性和成員,把它們組合在一起

4.6.不使用switch語句的狀态機

5.延遲計算

5.1.可以傳遞函數而不是傳遞實際的值,并在需要值的時候調用這些函數

5.2.純粹的面向對象結構可以實作,但是代碼比函數式多得多

5.3.許多函數式程式設計語言共有的特征

5.3.1.所有内容都是盡可能晚計算的

5.4.lambda

5.4.1.匿名函數

5.4.2.一次性函數

5.4.2.1.隻會引用這種函數一次,是以為其命名就成了多餘的工作

6.立即計算

6.1.立即得到并傳遞值,即使我們在以後決定丢棄該值

6.2.指令式程式設計語言(如TypeScript、Java、C#和C++)

7.一階函數

7.1.普通函數

7.2.接受一個或多個非函數實參并傳回一個非函數類型的“标準”函數

8.高階函數

8.1.定義:把所有接受或傳回其他函數的函數

8.1.1.二階函數

8.1.1.1.接受一個一階函數作為實參或者傳回一個一階函數的函數

8.1.2.三階函數

8.1.2.1.接受二階函數作為實參或者傳回二階函數的函數

8.2.基礎算法

8.2.1.map()

8.2.1.1.給定某個類型的值的一個集合

8.2.1.2.對其中每個值調用一個函數

8.2.1.3.傳回結果集合

8.2.1.4.自制map

8.2.1.4.1.一個T數組和一個函數作為實參

8.2.1.4.2.該實參函數接受項目T作為實參,并傳回U類型的一個值

8.2.1.4.3.函數把結果添加到一個U數組中

8.2.1.5.C# System.Linq Select()

8.2.1.6.Java java.util.stream map()

8.2.2.filter()

8.2.2.1.給定一個資料項集合和一個條件

8.2.2.2.過濾掉不滿足該條件的資料項

8.2.2.3.傳回滿足該條件的資料項集合

8.2.2.4.自制filter

8.2.2.4.1.輸入數組的類型為T

8.2.2.4.2.過濾函數接受T作為實參,并傳回boolean結果

8.2.2.4.2.1.謂詞

8.2.2.4.2.1.1. 接受一個實參并傳回一個boolean的函數

8.2.2.4.3.傳回過濾後的輸出

8.2.2.5.C# System.Linq Where()

8.2.2.6.Java java.util.stream filter()

8.2.3.reduce()

8.2.3.1.将所有集合項合并為一個值

8.2.3.1.1.建立一個初始值

8.2.3.1.2.周遊集合并把每個資料項與累積項合并,不斷累積結果

8.2.3.1.3.周遊完集合後傳回累積結果

8.2.3.2.自制reduce

8.2.3.2.1.泛型函數

8.2.3.2.1.1.實參為T數組

8.2.3.2.1.2.實參T類型的一個初始值

8.2.3.2.1.2.1. 需要處理輸入數組為空的情況

8.2.3.2.1.3.實參一個接受兩個T類型的實參并傳回T類型的結果

8.2.3.3.C# System.Linq Aggregate()

8.2.3.4.Java java.util.stream reduce()

8.2.3.5.沒有幺半群時

8.2.3.5.1.考慮初始值是什麼

8.2.3.5.2.在哪個方向上進行縮減

8.3.抽象代數

8.3.1.處理集合以及集合上的操作

8.3.2.T值集合上的一個操作

8.3.2.1.類型T的一個操作接受兩個T作為實參,并傳回另一個T,即(T, T) => T

8.3.3.機關元

8.3.3.1.T的一個元素id

8.3.3.2.操作op(x, id) == op(id, x) == x

8.3.3.3.id與其他任何元素合并起來,并不會改變其他元素

8.3.3.3.1.操作是加法時,機關元是0

8.3.3.3.2.操作是乘法時,機關元是1

8.3.3.3.3.操作為字元串連接配接時,機關元是“”(空字元串)

8.3.4.相關性

8.3.4.1.操作的一個屬性

8.3.4.2.對元素序列應用操作的順序并不重要,因為最終結果是相同的

8.3.4.3.op(x, op(y, z)) == op(op(x, y), z)

8.3.4.3.1.加法

8.3.4.3.2.乘法

8.3.4.3.3.減法

8.3.4.3.4.連接配接兩個字元串的首字母

8.3.5.幺半群(monoid)

8.3.5.1.有一個機關元

8.3.5.2.具有相關性

8.3.5.3.不要求提供初始值

8.3.5.3.1.在集合為空時預設使用機關元

8.3.6.半群(semigroup)

8.3.6.1.沒有機關元

8.3.6.1.1.把初始值放到第一個元素的左邊或者最後一個元素的右邊很重要

8.3.6.2.具有相關性

繼續閱讀