了解工会案例
Understanding union cases
我有一些这样的类型:
type Workshop = { Start: DateTime; End: DateTime }
type Mounting = { Start: DateTime; End: DateTime }
type FixedWorkTime = { Start: DateTime; End: DateTime }
type WorkTime =
| Workshop of Workshop
| Mounting of Mounting
type ApprovedWorkTime =
| ExistingWorkTime of WorkTime
| FixedWorkTime of FixedWorkTime
现在我想用这个签名创建一个函数WorkTime -> ApprovedWorkTime
let FixWorkTime (workTime: WorkTime) : ApprovedWorkTime =
match workTime with
| WorkTime.Workshop workshop -> ApprovedWorkTime.ExistingWorkTime { Start = workshop.Start, End = workshop.End }
| WorkTime.Mounting mounting -> ApprovedWorkTime.FixedWorkTime { Start = mounting.Start, End = mounting.End }
match
编译失败并出现此错误:
This expression was expected to have type 'WorkTime' but here has type 'FixedWorkTime'
我该如何解决这个问题?
在记录的字段之间使用分号,而不是逗号。每当您看到逗号时,就假设它表示一个元组。
其次,ExistingWorkTime是WorkTime的,WorkTime也是一个DU,所以你有层次。
let fixWorkTime (workTime: WorkTime) : ApprovedWorkTime =
match workTime with
| Workshop workshop -> ExistingWorkTime (Workshop { Start = workshop.Start; End = workshop.End })
| Mounting mounting -> FixedWorkTime { Start = mounting.Start; End = mounting.End }
这里:
ApprovedWorkTime.ExistingWorkTime { Start = workshop.Start, End = workshop.End }
您正在尝试使用 ExistingWorkTime
构造函数构造 ApprovedWorkTime
的值,并且将记录作为参数传递给它。
但根据其定义:
| ExistingWorkTime of WorkTime
它不需要记录,或者需要 WorkTime
类型的值。
所以修复它的最短方法是将它 workTime
作为参数:
ApprovedWorkTime.ExistingWorkTime workTime
虽然我严重怀疑这是你的意思。
另外,我想指出您的类型不必要地复杂。看:每个值都有相同的字段,它们只是构造函数不同,每次在值之间转换时都必须来回铲这些字段。
一个更高效的模型应该在顶层有 Start
和 End
字段,以及作为第三个字段的工作类型:
type WorkTime<'kind>= { Start: DateTime; End: DateTime; Kind: 'kind }
type WorkTimeKind = Workshop | Mounting
type ApprovedWorkTimeKind = ExistingWorkTime of WorkTime | FixedWorkTime
简单的解决方法是使类型匹配,正如其他答案已经解释的那样:
let FixWorkTime (workTime: WorkTime) : ApprovedWorkTime =
match workTime with
| WorkTime.Workshop _ -> ExistingWorkTime workTime
| WorkTime.Mounting mounting -> FixedWorkTime { Start = mounting.Start; End = mounting.End }
不过,我可能会稍微更改一下您的类型,使它们更具可组合性:
type Interval = { Start: DateTime; End: DateTime }
type WorkTime =
| Workshop of Interval
| Mounting of Interval
type ApprovedWorkTime =
| ExistingWorkTime of WorkTime
| FixedWorkTime of Interval
let FixWorkTime (workTime: WorkTime) : ApprovedWorkTime =
match workTime with
| Workshop _ -> ExistingWorkTime workTime
| Mounting interval -> FixedWorkTime interval
我有一些这样的类型:
type Workshop = { Start: DateTime; End: DateTime }
type Mounting = { Start: DateTime; End: DateTime }
type FixedWorkTime = { Start: DateTime; End: DateTime }
type WorkTime =
| Workshop of Workshop
| Mounting of Mounting
type ApprovedWorkTime =
| ExistingWorkTime of WorkTime
| FixedWorkTime of FixedWorkTime
现在我想用这个签名创建一个函数WorkTime -> ApprovedWorkTime
let FixWorkTime (workTime: WorkTime) : ApprovedWorkTime =
match workTime with
| WorkTime.Workshop workshop -> ApprovedWorkTime.ExistingWorkTime { Start = workshop.Start, End = workshop.End }
| WorkTime.Mounting mounting -> ApprovedWorkTime.FixedWorkTime { Start = mounting.Start, End = mounting.End }
match
编译失败并出现此错误:
This expression was expected to have type 'WorkTime' but here has type 'FixedWorkTime'
我该如何解决这个问题?
在记录的字段之间使用分号,而不是逗号。每当您看到逗号时,就假设它表示一个元组。
其次,ExistingWorkTime是WorkTime的,WorkTime也是一个DU,所以你有层次。
let fixWorkTime (workTime: WorkTime) : ApprovedWorkTime =
match workTime with
| Workshop workshop -> ExistingWorkTime (Workshop { Start = workshop.Start; End = workshop.End })
| Mounting mounting -> FixedWorkTime { Start = mounting.Start; End = mounting.End }
这里:
ApprovedWorkTime.ExistingWorkTime { Start = workshop.Start, End = workshop.End }
您正在尝试使用 ExistingWorkTime
构造函数构造 ApprovedWorkTime
的值,并且将记录作为参数传递给它。
但根据其定义:
| ExistingWorkTime of WorkTime
它不需要记录,或者需要 WorkTime
类型的值。
所以修复它的最短方法是将它 workTime
作为参数:
ApprovedWorkTime.ExistingWorkTime workTime
虽然我严重怀疑这是你的意思。
另外,我想指出您的类型不必要地复杂。看:每个值都有相同的字段,它们只是构造函数不同,每次在值之间转换时都必须来回铲这些字段。
一个更高效的模型应该在顶层有 Start
和 End
字段,以及作为第三个字段的工作类型:
type WorkTime<'kind>= { Start: DateTime; End: DateTime; Kind: 'kind }
type WorkTimeKind = Workshop | Mounting
type ApprovedWorkTimeKind = ExistingWorkTime of WorkTime | FixedWorkTime
简单的解决方法是使类型匹配,正如其他答案已经解释的那样:
let FixWorkTime (workTime: WorkTime) : ApprovedWorkTime =
match workTime with
| WorkTime.Workshop _ -> ExistingWorkTime workTime
| WorkTime.Mounting mounting -> FixedWorkTime { Start = mounting.Start; End = mounting.End }
不过,我可能会稍微更改一下您的类型,使它们更具可组合性:
type Interval = { Start: DateTime; End: DateTime }
type WorkTime =
| Workshop of Interval
| Mounting of Interval
type ApprovedWorkTime =
| ExistingWorkTime of WorkTime
| FixedWorkTime of Interval
let FixWorkTime (workTime: WorkTime) : ApprovedWorkTime =
match workTime with
| Workshop _ -> ExistingWorkTime workTime
| Mounting interval -> FixedWorkTime interval