gpt4 book ai didi

F# 列表模式匹配限制还是只是写得不好?

转载 作者:行者123 更新时间:2023-12-02 18:27:19 25 4
gpt4 key购买 nike

给定一些CreditScoreInput:

type CreditScoreInput = { id: string; score: string; years: int }

let input = [
{ id = "CUSTOMER001"; score = "Medium"; years = 1 }
{ id = "CUSTOMER001"; score = "Medium"; years = 1 }
{ id = "CUSTOMER002"; score = "Medium"; years = 10 }
{ id = "CUSTOMER003"; score = "Bad"; years = 0 }
{ id = "CUSTOMER003"; score = "Bad"; years = 0 }
{ id = "CUSTOMER003"; score = "Bad"; years = 0 }
{ id = "CUSTOMER004"; score = "Good"; years = 0 }
{ id = "CUSTOMER005"; score = "Good"; years = 10 }
]

我的函数validateDuplicates正在寻找重复项:

let validate list =
match list with
| [] -> failwith "No customers supplied!"
| _ -> list

let validateDuplicates (group:string * list<CreditScoreInput>) =
match group with
| (id, g) when g.Length = 1 -> printf $"No duplicates for {id} is OK.\n"
| (id, [input1; input2]) -> printf $"Two duplicates for {id} is OK.\n"
| (id, g) when g.Length > 2 -> printf $"More than two duplicates for {id} is NOT OK.\n"

true

input
|> validate
|> List.groupBy (fun i -> i.id)
|> List.forall (fun i -> i |> validateDuplicates)
|> ignore

validateDuplicates 内部,我注意到 group 下有一点弯曲,导致出现警告:

Incomplete pattern matches on this expression. For example, the value (_,[_;_;_]) may indicate a case not covered by the pattern(s). However, a pattern rule with a when clause might successfully match this value.

有没有办法可以让编译器很好地发挥作用以避免出现此警告?

更新

我不确定是否应该在这里这样做,但以下是我根据出色的指导进行的更改:

let validateDuplicates (group:string * list<CreditScoreInput>) =
match group with
| (id, [_]) -> printf $"No duplicates for {id} is OK.\n"
| (id, [_; _]) -> printf $"Two duplicates for {id} is OK.\n"
| (id, g) -> printf $"More than two duplicates for {id} is NOT OK.\n"

input
|> validate
|> List.groupBy (fun i -> i.id)
|> List.iter (fun i -> i |> validateDuplicates)

最佳答案

只需删除最后一个 when 子句,因为您知道它永远是 true:

    match group with
| (id, g) when g.Length = 1 -> printf $"No duplicates for {id} is OK.\n"
| (id, [input1; input2]) -> printf $"Two duplicates for {id} is OK.\n"
| (id, g) -> printf $"More than two duplicates for {id} is NOT OK.\n"

证明:

  • g.Length 永远不能为负数或 0
  • 如果g.Length为1,那么它将匹配第一种情况
  • 如果g.Length为2,那么它将匹配第二种情况
  • 因此,如果控制达到第三种情况,g.Length 将始终 > 2。

以下是我建议您编写此代码的方法:

let validateDuplicates (id, g : List<_>) =
match g.Length with
| 0 -> failwith "Unexpected"
| 1 -> printf $"No duplicates for {id} is OK.\n"
| 2 -> printf $"Two duplicates for {id} is OK.\n"
| _ -> printf $"More than two duplicates for {id} is NOT OK.\n"

input
|> validate
|> List.groupBy (fun i -> i.id)
|> List.iter validateDuplicates

我所做的更改是:

  • 使用 List.iter 而不是通过管道将 List.forall 传递到 ignore 中。
  • 在调用 validateDuplicates 时消除不需要的 lambda。
  • 使用模式匹配解构 validateDuplicates 的输入
  • 直接匹配 g.Length,而不是使用 when 子句。
  • 防御性编程:显式检查空列表以明确您的意图。

您可能还想考虑通过 F# 的 Result 使您的验证函数变得纯粹(即无副作用)。类型。

关于F# 列表模式匹配限制还是只是写得不好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69957608/

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