深入探討 F# 之 List

栏目: ASP.NET · 发布时间: 6年前

内容简介:F# 除了使用 .NET Framework 所提供的型別外,自己還定義了不少適合 FP 的型別,其中最常用的就是macOS High Sierra 10.13.3.NET Core SDK 2.1.101

F# 除了使用 .NET Framework 所提供的型別外,自己還定義了不少適合 FP 的型別,其中最常用的就是 List ,但這與 C# 的 List<T> 不同,反而類似 C# 的 ImmutableList<T>

Version

macOS High Sierra 10.13.3

.NET Core SDK 2.1.101

JetBrains Rider 2017.3.1

F# 4.1

Definition

List

將相同型別的 value 整合成單一 value,且每個 element 必須為 immutable

簡單來說,F# 的 List 就是 linked list 資料結構,為了實現 FP 的 Immutability,每個 element 建立後就不可再修改。

建立 List

List Literal

let myList = [ 1; 2; 3 ]
// 1; 2; 3

List 使用 [] 中括號表示,element 之間以 ; 隔開。

深入探討 F# 之 List

  1. List 天生就是泛型,不過並不需要如 C# 宣告泛型型別 List<int> ,Type Inference 會自動推導出 int list

F# 的型別都是寫在後面,不過 List 例外,element 型別寫在 list 前面

let myList = [
    1 // Number one
    2 // Number two
    3 // Number three
]
// 1; 2; 3

List 也可以使用換行的方式,此時可以不用加 ; 隔開,適用於 element 量較多時,或需要在 element 加上註解時。

let myControlList : Control list = [ new Button(); new CheckBox() ]

List 的 element 必須相同型別,若 element 是物件時,則有例外。基於 里氏替換原則 ,若 element 的型別為 父類別interface 時,則 element 允許基於相同 父類別interface 的物件。

let list123 = []

空 list 則以 [] 表示。

List Range

let myList = [ 1 .. 10 ]
// 1; 2; 3; 4; 5; 6; 7; 8; 9; 10

若 list 的資料有規律性,則不必全部列出,可使用 .. ,只要列出頭跟尾即可。

let myList = [ 1 .. 2 .. 10 ]
// 1; 3; 5; 7; 9

若 list 資料為 等差級數 ,則可在 .... 之間加上 step value,其中 step value 也可以是 負數

List Comprehension

若資料的變化性更大,已經無法單純使用 List Range 描述,則可使用更進階的 List Comprehension 表示。

let myList = [
    for i in 1..10 do
        yield i * i
]
// 1; 4; 9; 16; 25; 36; 49; 64; 81; 100

直接將 for ... in … do 寫在 [] 之內, yield 的 expression 即為 element。

let myList = [for i in 1..10 -> i * i]
// 1; 4; 9; 16; 25; 36; 49; 64; 81; 100

亦可將 do yield 省略,直接將 for ... in ... -> 寫在 [] 內,將 expression 寫在 -> 之後。

對於簡單的 expression,建議使用 for ... in ... -> 語法較精簡,若還需更複雜的描述,則必須使用 for ... in ... do yield

List Operator

:: Operator

let myList1 = [ 1; 2; 3 ]
let myList2 = 0 :: myList1

將 value 加到 : 之前, 將加到 list 最前面。

@ Operator

let myList1 = [ 1; 2; 3 ]
let myList2 = [ 4; 5; 6 ]
let myList3 = myList1 @ myList2
// 1; 2; 3; 4; 5; 6

@ 將兩個 list 合併為一個 list。

List Property

List 本身提供了不少 property 可用。

Head

‘T

獲得 List 第 1 個 element。

let myList = [ 1 .. 3 ]

printf "%d" myList.Head
// 1

Tail

‘T list

獲得第 1 個 element 除外,剩下的 list

let myList = [ 1 .. 3 ]

myList.Tail
|> List.iter (printf "%d;")
// 2;3;

就算 Tail 只剩下 1 個 element,仍然是 1 個 element 的 list。

isEmpty

bool

判斷 list 是否為空

let myList = [ 1 .. 2 ]

printf "%b" myList.IsEmpty
// false

Item

‘T

獲得指定 index 的 element 的值

let myList = [ 1 .. 3 ]

printf "%d" (myList.Item 2)
// 3

List 的 index 為 zero-based。

Length

int

獲得 list 的 element 個數

let myList = [ 1 .. 3 ]

printf "%d" myList.Length

Recursive Function

let rec sum list =
   match list with
   | head :: tail -> head + sum tail
   | [] -> 0

[ 1 .. 3 ]
|> sum
|> printf "%d"
// 6

List 在配合 recursive function 時,在 Pattern Matching 常搭配 head :: tail ,直接將 list 拆成兩半,然後將 tail 傳入 recursive function 繼續運算。

Conclusion

  • List 為 F# 最常用的 collection,概念雖然不難,但有一些 F# 獨特的語法,還是得花一點時間熟悉

Reference

Microsoft Docs , Lists

Wikibooks , F Sharp Programming/Lists

Chris Smith , Mastering F# Lists

Chris Smith , Pramming F# 3.0 2nd


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C++编程思想(第1卷)

C++编程思想(第1卷)

[美] Bruce Eckel / 刘宗田、袁兆山、潘秋菱 / 机械工业出版社 / 2002-9 / 59.00元

《C++编程思考》第2版与第1版相比,在章节安排上有以下改变。增加了两章:“对象的创建与使用”和“C++中的C”,前者与“对象导言”实际上是第1版“对象的演化”一章的彻底重写,增加了近几年面向对象方法和编程方法的最瓣研究与实践的有效成果,后者的添加使不熟悉C的读者可以直接使用这本书。删去了四章:“输入输出流介绍”、“多重继承”、“异常处理”和“运行时类型识别”,删去的内容属于C++中较复杂的主题,......一起来看看 《C++编程思想(第1卷)》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具