Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# match question

Tags:

f#

this is what i have so far:

type u = {str : string} //some type that has some property str (for simplicity, only one)
type du=
   | A of u
   | B of u // some discriminated union that carries u with it

then, somewhere i have a sequence of du that i am doing distinctBy and the property to do distinct is str. best i could come up with is this:

Seq.distinctBy (fun d -> match d with (A u|B u) -> u.str)

the code works, but i don't like having to match on a and b of the discriminated union and would like to replace the match with something.

question is, what? :)

EDIT:

in my case, a and b of the discriminated union will always carry same type u with them, one solution is to get rid of du and add it's string form to type u and simplify this whole mess, but i would like to keep it this way for now because i was going to do matches and such on the a and b...

like image 642
Alex Avatar asked May 11 '26 09:05

Alex


1 Answers

How about doing the match one time as a property of 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";}]

However, I have a couple ideas which may model the relationship between u and du better while satisfying your "EDIT" concerns. One way is simply using tuples:

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"

Another way is to switch it around and add du to 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"
like image 154
Stephen Swensen Avatar answered May 13 '26 11:05

Stephen Swensen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!