Как насчет того, чтобы сделать совпадение один раз как свойство du?
type u = {str : string}
type du =
| A of u
| B of u with
member this.U =
match this with
(A u | B u) -> u
[A {str="hello"}; B {str="world"}; A {str="world"}]
|> Seq.distinctBy (fun x -> x.U.str)
//val it : seq<du> = seq [A {str = "hello";}; B {str = "world";}]
Однако у меня есть пара идей, которые могут лучше моделировать отношения между вами и du, удовлетворяя при этом ваши проблемы "РЕДАКТИРОВАНИЯ".Одним из способов является просто использование кортежей:
type u = {str : string}
type du =
| A
| B
//focus on type u
[A, {str="hello"}; B, {str="world"}; A, {str="world"}]
|> Seq.distinctBy (fun (_,x) -> x.str)
//val it : seq<du * u> = seq [(A, {str = "hello";}); (B, {str = "world";})]
//focus on type du
let x = A, {str="hello"}
match x with
| A,_ -> "A"
| B,_ -> "B"
//val it : string = "A"
Другой способ - переключить его и добавить du к u:
type du =
| A
| B
type u = { case : du; str : string}
//focus on type u
[{case=A; str="hello"}; {case=B; str="world"}; {case=A; str="world"}]
|> Seq.distinctBy (fun x -> x.str)
//val it : seq<u> = seq [{case = A;
// str = "hello";}; {case = B;
// str = "world";}]
//focus on type du
let x = {case=A; str="hello"}
match x with
| {case=A} -> "A"
| {case=B} -> "B"
//val it : string = "A"