Search code examples
f#type-constraints

Filter by constraint


Ok, I realise this might be a weird question. But I need to ask it anyway. It goes as follows:

Suppose I have something like the following:

type Foo() =
    member this.MyFooFun i = 2*i

type Bar() =
    inherit Foo()
    member this.MyBarFun i = 3*i

type Baz() =
    inherit Foo()
    member this.MyBazFun i = 5*i

type FooSeq = seq<Foo>

What I want to do, is to filter out all the Foo's from a FooSeq that has the member MyBarFun. Is it possible to do anything like that?

I realise I will probably have to use the :? operator to check whether each element is a Bar, but as I said - I have to ask. The reason I would rather not do this, is that the types corresponding to Foo, Bar and Baz lies in a library developed somewhere else in the company. And there might be added more types containing the MyBarFun-member at any given time.


Solution

  • If you only want to filter on the subtype, it's easy:

    let foos = candidates |> Seq.filter (fun x -> not (x :? Bar))
    

    If you explicitly want to filter away types that have a member called "MyBarFun", you'll need to use reflection:

    let foos' =
        candidates
        |> Seq.filter (fun x ->
            not (x.GetType().GetMembers() |> Array.exists (fun m ->
                m.Name = "MyBarFun")))