部分活动模式

时间:2017-11-27 11:55:00

标签: f# functional-programming f#-interactive

我必须为学校写一个函数,它从扑克手中确定它是否有两对。我应该用部分活动模式来做,但我被困在这里。

let (|TwoPairs|_|) (x: (string * string) list) =
    x
    |> List.groupBy snd
    |> List.sortByDescending fst
    |> List.filter (fun (_, v) -> v |> List.length = 2)
    |> List.length = 2

let x2 =
    match [("S", "2"); ("S", "6"); ("S", "6"); ("S", "4"); ("S", "2")] with
    | TwoPairs p -> sprintf "Two pairs"
    | _ -> "Nothing"

如何将最后一次比较作为一个选项给出,在这种情况下应该在某些_中应该包含什么?

1 个答案:

答案 0 :(得分:2)

我认为活动模式函数的最后一行非常混乱,因为缩进和由运算符优先级引起的隐式分组。我会这样写它来返回一个选项:

let (|TwoPairs|_|) (x: (string * string) list) =
    x
    |> List.groupBy snd
    |> List.sortByDescending fst
    |> List.filter (fun (_, v) -> v |> List.length = 2)
    |> List.length
    |> function 2 -> Some () | _ -> None

当您返回Option<unit>时,您不必绑定到p,因为它将是单位并表示缺少值。所以你会使用这样的模式:

let x2 =
    match [("S", "2"); ("S", "6"); ("S", "6"); ("S", "4"); ("S", "2")] with
    | TwoPairs -> sprintf "Two pairs"
    | _ -> "Nothing"

我不确定在这里使用活动模式是否有任何好处。有一个返回bool的普通函数会更简单:

if twoPairs [("S", "2"); ("S", "6"); ("S", "6"); ("S", "4"); ("S", "2")]
then sprintf "Two pairs"
else "Nothing"