2012-07-26 14 views
1

有沒有辦法做到這一點?根據會員基礎類型篩選包含歧視工會成員的記錄清單

type EntryDetails = 
| ADetails of TypeADetails 
| BDetails of TypeBDetails 
| ... 


type Entry = { A, B, C, ... Details:EntryDetails} 

let filter (list:list<Entry>) myType = List.filter (fun x -> x.Details is myType) 

請注意我希望myType是一個參數,而不是硬編碼類型。

我試過,但它顯然是行不通的:

let filterDetails (entry:Entry) detailType = match entry.Details with 
               | detailType -> true 
               | _ -> false 

回答

1

這不是你的問題一個確切的解決方案,但是它很接近,容易實現 - 關於使用部分活躍模式與List.choose如何,像這樣:

type EntryDetails = 
    | ADetails of int 
    | BDetails of byte 
    | CDetails of string 

type Entry = { Foo : unit; Bar : unit; Details : EntryDetails; } 

module Patterns = 
    let (|ADetails|_|) x = 
     match x.Details with 
     | ADetails _ -> Some x 
     | _ -> None 

    let (|BDetails|_|) x = 
     match x.Details with 
     | BDetails _ -> Some x 
     | _ -> None 

    let (|CDetails|_|) x = 
     match x.Details with 
     | CDetails _ -> Some x 
     | _ -> None 

module internal Test = 
    let private testData = 
     let baseData = { Foo =(); Bar =(); Details = ADetails 0; } 
     [ { baseData with Details = ADetails 10; }; 
      { baseData with Details = BDetails 7uy; }; 
      { baseData with Details = BDetails 92uy; }; 
      { baseData with Details = ADetails 32; }; 
      { baseData with Details = CDetails "foo"; }; 
      { baseData with Details = BDetails 2uy; }; 
      { baseData with Details = ADetails 66; }; 
      { baseData with Details = CDetails "bar"; }; 
      { baseData with Details = CDetails "baz"; }; ] 

    let results = 
     testData 
     |> List.choose Patterns.(|ADetails|_|) 

如果你的代碼粘貼到fsi,你應該得到以下輸出:

(* Snip ... removed irrelevant type signatures *) 
module internal Test = begin 
    val private testData : Entry list = 
    [{Foo = null; 
     Bar = null; 
     Details = ADetails 10;}; {Foo = null; 
           Bar = null; 
           Details = BDetails 7uy;}; 
    {Foo = null; 
     Bar = null; 
     Details = BDetails 92uy;}; {Foo = null; 
            Bar = null; 
            Details = ADetails 32;}; 
    {Foo = null; 
     Bar = null; 
     Details = CDetails "foo";}; {Foo = null; 
            Bar = null; 
            Details = BDetails 2uy;}; 
    {Foo = null; 
     Bar = null; 
     Details = ADetails 66;}; {Foo = null; 
           Bar = null; 
           Details = CDetails "bar";}; 
    {Foo = null; 
     Bar = null; 
     Details = CDetails "baz";}] 

    val results : Entry list = 
    [{Foo = null; 
     Bar = null; 
     Details = ADetails 10;}; {Foo = null; 
           Bar = null; 
           Details = ADetails 32;}; 
    {Foo = null; 
     Bar = null; 
     Details = ADetails 66;}] 
end 

正如您所見,Test.results列表已被過濾,因此它只包含Entry項,其Details字段的類型爲ADetails

+0

非常感謝。這在功能上正是我想要的。不過,每次我向歧視聯盟添加一個類型時,我仍然必須編寫枯燥的樣板Patterns._方法。哦,我試過了。 – CxDoo 2012-07-26 12:10:12