Carlo V. Dango
Carlo V. Dango

Reputation: 13882

Filtering list with discriminating union type to a single type

Given a type

type C = Circle of int | Rectangle of int * int

and a collection

let l = [ Circle(1); Circle(2); Rectangle(1,2)]

I want to handle only circles

 let circles = l |> List.filter(fun x-> match x with 
                                        | Circle(l) -> true
                                        | _ -> false)

But my circles are still of type C, thus I cannot do

for x in circles do
  printf "circle %d" x.??

I have to do

for x in circles do
  match x with 
  | Circle(l) -> printf "circle %d" l
  | _ -> ())

seems wrong..

Upvotes: 15

Views: 2735

Answers (2)

Dima_
Dima_

Reputation: 81

l|>Seq.iter (function |Circle l->printf "circle %d" l|_->())

Upvotes: 3

Jack P.
Jack P.

Reputation: 11525

Use List.choose -- it's like List.filter and List.map rolled into one.

let circles =
    l |> List.choose(fun x ->
        match x with 
        | Circle l -> Some l
        | _ -> None)

for x in circles do
  printf "circle %d" x

Upvotes: 33

Related Questions