深入探討 F# 之 Tuple

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

内容简介:macOS High Sierra 10.13.3.NET Core SDK 2.1.101

Tuple 是 FP 語言常見的型別,且 C# 7.0 也開始有 Tuple ,讓我們藉由 F# 學習該如何活用 Tuple

Version

macOS High Sierra 10.13.3

.NET Core SDK 2.1.101

JetBrains Rider 2017.3.1

F# 4.1

Definition

Tuple

將不同型別的 value 整合成單一 value

在將不同型別整合成單一型別,F# 提供了 3 種方式:

  1. Tuple

  2. Record

  3. Union

其中 TupleRecord 提供類似 AND 的方式將不同型別加以整合,而 Union 則提供類似 OR 的方式將不同型別加以整合。

RecordTuple 的差異在於 Record 為 named type,須事先定義型別,而 Tuple 則為 unmamed type,可直接使用,Type Inference 會幫我們推導出 Tuple 型別。

建立 Tuple

相同型別

let dinner = ("green eggs", "ham")

green eggsham 兩個 string 整合成一個 dinner tuple。

深入探討 F# 之 Tuple

Type Inference 自動推導出 dinner tuple 為 string * string

Tuple 型別表示法,是以 * 串接各型別,因為 Tuple 概念是 AND,所以使用 *

不同型別

let dinner = ("green eggs", 16);

若只是將 tuple 用在相同型別,則顯示不出 tuple 的威力,相同型別大可使用 ArrayList ,tuple 讓我們可以將 不同型別 包在同一個 tuple。

深入探討 F# 之 Tuple

Type Inference 自動推導出 dinner tuple 為 string * int

let nested = (1, (2.0, 3M), (4L, "5", '6'))

甚至也可以巢狀的方式使用 tuple。

分解 Tuple

Tuple 將不同 value 整合單一 tuple 後,馬上會遇到另外一個問題:

Q:如何將單一 tuple 分解成 value?

F# 提供 3 種方式:

  • fst()snd()
  • Let Binding
  • Pattern Matching

fst() 與 snd()

let students = ("John", "Smith")

printfn "%s" (fst students)
printfn "%s" (snd students)

若只是兩個 element 的 tuple,可使用 fst()snd() function 分解 tuple。

沒有 trd() ,但可自行建立 let trd (_, _, z) = z

Let Binding

let students = ("John", "Smith", "Jessie")
let student1, student2, student3 = students

printfn "%s, %s, %s" student1 student2 student3

直接使用 let ,會自動將 tuple 分解到各別 value,也沒 element 數限制。

let students = ("John", "Smith", "Jessie")
let student1, student2, _ = students

printfn "%s, %s" student1 student2

若只需部分 element,可使用 _ 忽略之。

let students = ("John", "Smith", "Jessie")

let print (student1, student2, student3) = 
    printfn "%s %s %s" student1 student2 student3
    
students
|> print

當 tuple 傳進 function 參數時,可直接分解成 value。

Pattern Matching

let students = ("John", "Smith", "Jessie")

let print students = 
    match students with
    | (student1, student2, student3) -> printfn "%s %s %s" student1 student2 student3
    
students
|> print

亦可使用 Pattern Matching 對 tuple 加以分解。

活用 Tuple

將 Tuple 當成參數

let values = (2, 3, 4)

let add (x, y, z) = x + y + z
    
values
|> add
|> printfn "%d"

// 9

values 為 tuple,而 add()int * int * int -> int

values 傳進 add() 時,會自動分解成 xyz

Tuple vs. Partial Function Application
let add1 x y z = x + y + z
let add2 (x, y, z) = x + y + z

雖然都是 x + y + z ,但 add1()add2() 意義完全不同。

add1()int -> int -> int -> int

add2()int * int * int -> int

add1() 可使用 Partial Function Application 方式使用,也就是若只傳一個參數 int ,將回傳 int -> int -> int function,若傳入兩個參數 int ,將回傳 init -> int function。

add2() 則必須一次傳入整個 tuple,不能只傳 部分參數

Q:我該使用 Tuple 或 Partial Function Application 呢?

  • 完全視 設計考量語意
  • Partial Function Application 使用上會比 Tuple 靈活
  • 若你不希望被當成 Partial Function Application 使用,則使用 Tuple。

將 Tuple 當成回傳值

let divRem a b =
   let x = a / b
   let y = a % b
   (x, y)

有些 function 會希望一次回傳多個值,如 兩數相除 ,會希望同時傳回 商數餘數

傳統程式語言我們會回傳 ArrayList ,但有相同型別的限制;在 OOP 我們會回傳 Object ,但必須事先建立 class;但在 FP 我們可回傳 Tuple

Conclusion

  • Tuple 不用事先定義型別,可以直接使用,特別適合 function 只使用一次的 參數回傳值 型別
  • 在 OOP,若我們想將 多個參數 合併成 單一參數 ,或將 多回傳值 合併成 單一回傳值 ,我們必須使用 Object ,但常常糾結是否該特別開一個 class 型別;但在 FP,我們可以隨時使用 tuple,也能享受 compile 強型別的檢查

Reference

Microsoft Docs , Tuples

F# for fun and profit , Tuples

Chris Smith , Pramming F# 3.0 2nd


以上所述就是小编给大家介绍的《深入探討 F# 之 Tuple》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

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

游戏编程权威指南

游戏编程权威指南

Mike McShaffry 麦克沙福瑞、David “Rez” Graham 格雷海姆 / 师蓉、李静、李青翠 / 人民邮电 / 2016-3 / 99.00元

全书分为4个部分共24章。首部分是游戏编程基础,主要介绍了游戏编程的定义、游戏架构等基础知识。 第二部分是让游戏跑起来,主要介绍了初始化和关闭代码、主循环、游戏主题和用户界面等。 第三部分是核心游戏技术,主要介绍了一些*为复杂的代码 示例,如3D编程、游戏音频、物理和AI编程等。 第四部分是综合应用,主要介绍了网络编程、多道程序设计和用C#创建工具等,并利用前面所讲的 知识开发出......一起来看看 《游戏编程权威指南》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

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

正则表达式在线测试

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具