Reputation: 29199
See I have a single case discriminated union
type R = R of string * int * sting option * .....
And I got a value of R
.
let r: R = getAValue ()
Now I need to replace the first item of r
to an empty string and keep all other value. How to do it? Record type has the with
construct
let r' = { r with Item1 = "" }
I know it can use 'pattern match' to extract all the items and create a new one. But it seems very cumbersome.
Upvotes: 1
Views: 97
Reputation: 10350
I assume you do not want to involve reflection, do you?
Then, I believe your only option would be using pattern matching. The (quite limited) burden would be defining the r-ity
of your type R
as a pattern for matching.
Let's assume, for example, that your R wraps a tuple of 3 elements, i.e. has r-ity 3:
type R = R of string * int * string option
In this case all you need is to do define the following function:
let modR = function
| R(x,y,z) -> R("",y,z)
The signature of modR
is R -> R
, a quick check of your scenario:
let r = R("abc",1,None)
modR r
in fsi brings back
>
val it : R = R ("",1,None)
All you would need for applying the above to your specific R
is set the actual r-ity of your type into the pattern.
UPDATE: As Fyodor Soikin pointed, a matching function isn't needed at all for unwrapping a single-case DU (see the docs). The sought convertion function definition may be defined as simple as
let modR (R(_,y,z)) = R("",y,z)
UPDATE2: While considering the comment from ca9163d9 I recalled just another flavor of pattern matching, namely as Pattern. Using it while implementing the sought conversion in the form of DU member gives:
type R = R of string * int * string option with
member self.modR() = let R(_,b,c) as x = self in R("",b,c)
Also @FyodorSoikin and @kaefer have pointed out in the comments that as x
form isn't required for the simple DU unwrapping, similarly to terser modR
function definition above:
member self.modR() = let (R(_,b,c)) = self in R("",b,c)
Upvotes: 3