模式匹配记录类型

时间:2011-08-18 15:41:26

标签: .net f# functional-programming pattern-matching

让我们考虑以下Point记录类型:

type Point = { x:int; y:int }

我想创建一个谓词,告诉我某个Point是否在有效区域内。

let insideBounds p =
  let notInside c = c < 0 || c > 100
  match p with
  | {x=i; y=_} when notInside i -> false
  | {x=_; y=j} when notInside j -> false
  | _                           -> true

这是有效的,但我想知道是否有另一种方法可以实现与insideBounds签名相同的结果

let insideBounds {x=i; y=j}

相反,仍然使用模式匹配?

2 个答案:

答案 0 :(得分:6)

您可以定义活动模式,用于测试值是否在指定为参数的范围内:

let (|InRange|_|) (min, max) v = 
  if v >= min && v <= max then Some () else None

然后你可以像这样定义insideBounds

let insideBounds = function
  | { x = InRange (0, 100); y = InRange (0, 100) } -> true
  | _ -> false

x anad y成员都在指定范围内时,第一种情况匹配。活动模式返回option unit,这意味着它不绑定任何值。 (0, 100)是一个输入参数,当值(xy)在范围内时,模式匹配。

(在其他情况下`匹配10与InRange(0

答案 1 :(得分:4)

不确定

type Point = { x:int; y:int }

let insideBounds {x=i; y=j} =
  let notInside c = c < 0 || c > 100
  not (notInside i || notInside j)

我建议反转你的逻辑以使其更清晰:

let insideBounds {x=i; y=j} =
  let isInside c = c >= 0 && c <= 100
  isInside i && isInside j

作为一般规则,布尔函数/属性等更好是肯定的。这样,否定就会保留它的消极性,可以这么说。