有办法做到这一点吗?
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
答案 0 :(得分:2)
这不是你的问题的确切解决方案,但它非常接近且易于实现 - 如何使用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
的{{1}}项。