Using incomplete pattern matching as a filter?

Suppose I have the following code:

type Vehicle =
| Car  of string * int
| Bike of string

let xs = [ Car("family", 8); Bike("racing"); Car("sports", 2); Bike("chopper") ]

I can filter the list above using incomplete pattern matching in the imperative for the loop, for example:

> for Car(kind, _) in xs do
>    printfn "found %s" kind;;

found family
found sports
val it : unit = ()

but this will result in: 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.

Since ignoring the unsurpassed elements is my intention, is there any way to get rid of this warning?

And is there a way to make this work with a list without raising a MatchFailureException? for example something like this:

> [for Car(_, seats) in xs -> seats] |> List.sum;;
val it : int = 10
+5
source share
3 answers

, . , . , .

:

for x in xs do
    match x with
    | Car(kind, _) -> printfn "found %s" kind
    | _ -> ()

( )

, List.sumBy :

xs |> List.sumBy (function Car(_, seats) -> seats | _ -> 0)

, :

[for x in xs do
    match x with
    | Car(_, seats) -> yield seats
    | _ -> ()
] |> List.sum
+10

#nowarn --nowarn: ( , 25, FS0025).

, , (, choose).

+5

To explicitly indicate that you want to ignore unsurpassed cases, you can use List.chooseand return Nonefor these unsurpassed elements. Your codes can be written more idomatically as follows:

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
+5
source

All Articles