简化模式匹配

Ale*_*ler 1 f#

我有这些类型

type IntervalWithBreak = { Start: DateTime; End: DateTime }
type IntervalWithoutBreak = { Start: DateTime; End: DateTime; Break: TimeSpan }

type WorkTime =
  | Workshop of IntervalWithBreak
  | Mounting of IntervalWithBreak
  | Ill of IntervalWithoutBreak
 
type WorktimeDefinition = {Weekday: DayOfWeek}
Run Code Online (Sandbox Code Playgroud)

现在我想创建一个函数,它允许我查找与条件匹配的元素。workTime然而,在我使用此模式匹配之前,函数中的代码完成matches不会提供StartEnd字段。

let matches (worktime:WorkTime) (worktimeDefinition:WorktimeDefinition) =
  match worktime with
  | Workshop w -> w.Start.DayOfWeek = worktimeDefinition.Weekday
  | Mounting m -> m.Start.DayOfWeek = worktimeDefinition.Weekday
  | Ill i -> i.Start.DayOfWeek = worktimeDefinition.Weekday

List.find (matches worktime) definitions
Run Code Online (Sandbox Code Playgroud)

我可以有一个更通用的匹配,这样我就不必检查所有联合案例,而是匹配IntervalWithoutBreakand 吗IntervalWithBreak

我的类型定义是基于这个建议的。

Tom*_*cek 5

由于 case 的参数WorkshopMountingcase 的类型相同,因此您可以做的第一件事是将它们连接成 or 模式:

let matches (worktime:WorkTime) (worktimeDefinition:WorktimeDefinition) =
  match worktime with
  | Workshop m 
  | Mounting m -> m.Start.DayOfWeek = worktimeDefinition.Weekday
  | Ill i -> i.Start.DayOfWeek = worktimeDefinition.Weekday
Run Code Online (Sandbox Code Playgroud)

Ill这对于包含不同类型参数的情况不起作用。但由于它们都是记录,因此您也可以在模式匹配中解构记录:

let matches (worktime:WorkTime) (worktimeDefinition:WorktimeDefinition) =
  match worktime with
  | Workshop { Start = start } 
  | Mounting { Start = start }
  | Ill { Start = start } -> start.DayOfWeek = worktimeDefinition.Weekday
Run Code Online (Sandbox Code Playgroud)

由于您现在只有一种情况,您实际上可以使用 来编写此代码let,但我可能不会这样做。我认为match更具可读性。但仅供记录:

let matches (worktime:WorkTime) (worktimeDefinition:WorktimeDefinition) =
  let (Workshop { Start = s } | Mounting { Start = s } | Ill { Start = s }) = worktime
  s.DayOfWeek = worktimeDefinition.Weekday
Run Code Online (Sandbox Code Playgroud)