深入探討 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


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

查看所有标签

猜你喜欢:

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

设计模式

设计模式

[美] Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides / 李英军、马晓星、蔡敏、刘建中 等 / 机械工业出版社 / 2000-9 / 35.00元

这本书结合设计实作例从面向对象的设计中精选出23个设计模式,总结了面向对象设计中最有价值的经验,并且用简洁可复用的形式表达出来。书中分类描述了一组设计良好、表达清楚的软件设计模式,这些模式在实用环境下特别有用。此书适合大学计算机专业的学生、研究生及相关人员参考。 书中涉及的设计模式并不描述新的或未经证实的设计,只收录了那些在不同系统中多次使用过的成功设计。一起来看看 《设计模式》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

SHA 加密
SHA 加密

SHA 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具