Copying a union case but with a different meaning in F #

In F #, I want to construct an instance (correct terminology?) Of a discriminatory join based on an existing instance. Example:

type union Currency =
    | Dollar of int
    | Euro of int

let lowPrice = Dollar 100 (* or, it could be *) let lowPrice = Euro 100
let highPrice = (* of the same union case as lowPrice but with value 200 *)

      

What code can be inserted instead of a comment to create this effect?

+3


source to share


3 answers


You could do

let highPrice =
    let n = 200
    match lowPrice with
    | Dollar _ -> Dollar n
    | Euro _ -> Euro n

      

but units are probably better.



EDIT

Alternatively, perhaps you want

type MoneyType = Dollar | Euro
type Currency = Currency of MoneyType * int
let lowPrice = Currency(Dollar, 100)
let highPrice = 
    match lowPrice with
    | Currency(kind, _) -> Currency(kind, 200)

      

+5


source


I think it makes more sense to use units for this kind of problem - somthing like

[<Measure>] type Dollar
[<Measure>] type Euro

let lowprice = 100<Dollar>
let inline _highprice (newv:int) (oldv:int<'t>) : int<'t> = 
    LanguagePrimitives.Int32WithMeasure newv
let highprice = _highprice 200 lowprice

      



the transform function is a little tricky but will do what you want

+2


source


You can introduce new case union values ​​based on the existing value of the same case union using Reflection. To achieve this, simply add a member instance Same

to your discriminated union, which first deduces the specific case of the union from the instance self

, and then creates a new instance with the same case of the union, but is now populated with newVal

:

open Microsoft.FSharp.Reflection
type Currency =
    | Dollar of int
    | Euro of int

    member self.Same newVal : Currency =
        FSharpValue.MakeUnion(fst (FSharpValue.GetUnionFields(self,
                                       typeof<Currency>)), [|newVal|])
        |> unbox

      

Now applying it to lowPrice

below value

let lowPrice = Euro(100)
let highPrice = lowPrice.Same 200

      

You'll get highPrice : Currency = Euro 200

0


source







All Articles