ras*_*asx 2 f# pattern-matching
鉴于一些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 }
]
Run Code Online (Sandbox Code Playgroud)
我的功能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
Run Code Online (Sandbox Code Playgroud)
在里面validateDuplicates我注意到下面有一点弯曲group,导致警告:
该表达式的模式匹配不完整。例如,该值
(_,[_;_;_])可以指示未被模式覆盖的情况。但是,带有子句的模式规则when可能会成功匹配该值。
有没有办法可以很好地使用编译器来避免此警告?
我不确定我是否应该在这里这样做,但以下是我根据出色的指导进行的更改:
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)
Run Code Online (Sandbox Code Playgroud)
只要去掉最后一个when子句,因为你知道它永远是真的:
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"
Run Code Online (Sandbox Code Playgroud)
证明:
g.Length永远不能为负数或 0g.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
Run Code Online (Sandbox Code Playgroud)
我所做的更改是:
List.iter而不是管道List.forall到ignore.validateDuplicates。validateDuplicatesg.Length而不是 usingwhen子句。您可能还需要考虑通过 F# 的类型使您的验证函数变得纯粹(即无副作用)Result。
| 归档时间: |
|
| 查看次数: |
61 次 |
| 最近记录: |