假设我有以下代码:
type Vehicle =
| Car of string * int
| Bike of string
let xs = [ Car("family", 8); Bike("racing"); Car("sports", 2); Bike("chopper") ]
我可以使用不完整的模式匹配来过滤上面的列表,例如:
> for Car(kind, _) in xs do
> printfn "found %s" kind;;
found family
found sports
val it : unit = ()
但它会导致:warning FS0025: Incomplete pattern matches on this expression. For example, the value 'Bike (_)' may indicate a case not covered by the pattern(s). Unmatched elements will be ignored.
由于忽略了无与伦比的元素是我的意图,是否有可能摆脱这种警告?
有没有办法让list-comprehensions使用而不会导致MatchFailureException?例如类似的东西:
> [for Car(_, seats) in xs -> seats] |> List.sum;;
val it : int = 10
答案 0 :(得分:10)
两年前,您的代码有效,这是执行此操作的标准方法。然后,语言已被清理,设计决策是支持显式语法。出于这个原因,我认为忽略警告不是一个好主意。
代码的标准替代品是:
for x in xs do
match x with
| Car(kind, _) -> printfn "found %s" kind
| _ -> ()
(你也可以在pad样本中使用高阶函数)
对于另一个,List.sumBy很适合:
xs |> List.sumBy (function Car(_, seats) -> seats | _ -> 0)
如果您更喜欢坚持理解,这是明确的语法:
[for x in xs do
match x with
| Car(_, seats) -> yield seats
| _ -> ()
] |> List.sum
答案 1 :(得分:5)
您可以通过#nowarn
指令或--nowarn:
编译器选项使警告静音(通过警告编号,25
此处FS0025
)。
但更一般地说,不,最好的事情是明确过滤,就像在另一个答案中一样(例如使用choose
)。
答案 2 :(得分:5)
要明确声明您要忽略不匹配的案例,您可以使用List.choose
并返回None
这些不匹配的元素。您的代码可以用更加独特的方式编写,如下所示:
let _ = xs |> List.choose (function | Car(kind, _) -> Some kind
| _ -> None)
|> List.iter (printfn "found %s")
let sum = xs |> List.choose (function | Car(_, seats)-> Some seats
| _ -> None)
|> List.sum