gpt4 book ai didi

f# - 我什么时候应该在元组上使用记录?

转载 作者:行者123 更新时间:2023-12-03 12:35:35 25 4
gpt4 key购买 nike

我正在尝试在 F# 中练习域驱动设计,并偶然发现了以下问题:

当使用元组似乎需要更少的语法并且在模式匹配和整体使用场景方面似乎更强大时,为什么我要使用记录?

例如,如果我要使用元组来代替,我觉得我不再需要仅仅为了实现区分联合而创建记录类型。

type Name = { First:string 
Middle:string option
Last:string }

type Duration = { Hours:int
Minutes:int
Seconds:int }

type Module =
| Author of Name
| Title of string
| Duration of Duration

let tryCreateName (first, middle, last) =
{ First=first; Middle=Some middle; Last=last }

let tryCreateDuration (hours, minutes, seconds) =
{ Hours=hours; Minutes=minutes;Seconds=seconds }

let name = tryCreateName ("Scott", "K", "Nimrod")

let hours = 1
let minutes = 30
let seconds = 15

let duration = tryCreateDuration (hours, minutes, seconds)

我的想法准确吗?

在大多数情况下,是否需要元组而不是记录?

最佳答案

对于领域建模,我建议使用带有 的类型。命名元素 ;也就是记录、区分联合,也许还有偶尔的类或接口(interface)。

在结构上,记录和元组是相似的;用代数数据类型的说法,它们都是 产品类型 .

不同之处在于,对于元组,值的顺序很重要,并且每个元素的作用是隐含的。

> (2016, 1, 2) = (2016, 1, 2);;
val it : bool = true
> (2016, 1, 2) = (2016, 2, 1);;
val it : bool = false

在上面的示例中,您可能会猜到这些元组模拟日期,但究竟是哪些?是 2016 年 1 月的第二天吗?还是 2016 年 2 月的第一天?

另一方面,对于记录,元素的顺序无关紧要,因为您可以通过名称绑定(bind)它们并访问它们:
> type Date = { Year : int; Month : int; Day : int };;

type Date =
{Year: int;
Month: int;
Day: int;}

> { Year = 2016; Month = 1; Day = 2 } = { Year = 2016; Day = 2; Month = 1 };;
val it : bool = true

当您想要提取组成值时,它也更清楚。您可以轻松地从记录值中获取年份:
> let d = { Year = 2016; Month = 1; Day = 2 };;

val d : Date = {Year = 2016;
Month = 1;
Day = 2;}

> d.Year;;
val it : int = 2016

从元组中提取值要困难得多:
> let d = (2016, 1, 2);;

val d : int * int * int = (2016, 1, 2)

> let (y, _, _) = d;;

val y : int = 2016

当然,对于配对,您可以使用内置函数 fstsnd要访问元素,但对于具有三个或更多元素的元组,除非您进行模式匹配,否则您无法轻松获取值。

即使您定义了自定义函数,每个元素的角色仍然由其序数隐式定义。如果它们属于同一类型,则很容易将值的顺序弄错。

所以对于领域建模,我总是更喜欢显式类型,以便清楚发生了什么。

那么,元组永远不合适吗?

元组在其他情况下很有用。当您需要使用 临时类型 为了组合函数,它们比记录更合适。

Seq.zip 为例。 ,它使您能够组合两个序列:
let alphalues = Seq.zip ['A'..'Z'] (Seq.initInfinite ((+) 1)) |> Map.ofSeq;;

val alphalues : Map<char,int> =
map
[('A', 1); ('B', 2); ('C', 3); ('D', 4); ('E', 5); ('F', 6); ('G', 7);
('H', 8); ('I', 9); ...]

> alphalues |> Map.find 'B';;
val it : int = 2

正如您在此示例中所见,元组只是朝着实际目标迈出的一步,即按字母顺序排列的值的映射。如果我们想在表达式中组合值时必须定义记录类型,那将是很尴尬的。元组非常适合该任务。

关于f# - 我什么时候应该在元组上使用记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34856064/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com