Question

In F#, I want to construct an instance (correct terminology?) of a discriminated union 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 could I insert in place of the comment to create that effect?

Was it helpful?

Solution

You could do

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

but units of measure are probably better.

EDIT

Alternatively, maybe 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)

OTHER TIPS

I think for this sort of problem it is more appropriate to use units of measure - 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 conversion function is a little tricky but it will do what you want

You can make new union case values based on existing value of the same union case using Reflection. In order to achieve this just add instance member Same to your discriminated union, which first derives specific union case from the instance self and then constructs a new instance by the same union case, but 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 value below

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

you'll get highPrice : Currency = Euro 200

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top