Domanda

In F #, voglio costruire un'istanza (terminologia corretta?) di un'unione discriminata basata su un'istanza esistente.Esempio:

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 *)
.

Quale codice potrei inserire al posto del commento per creare quell'effetto?

È stato utile?

Soluzione

Potresti fare

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

Ma le unità di misura sono probabilmente migliori.

Modifica

In alternativa, forse vuoi

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)
.

Altri suggerimenti

Penso che per questo tipo di problema sia più appropriato usare unità di misura - qualcosa come

[<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
.

La funzione di conversione è un po 'complicata ma farà ciò che vuoi

È possibile effettuare nuovi valori del caso dell'Unione in base al valore esistente della stessa custodia dell'Unione utilizzando la riflessione.Per ottenere questo solo aggiungere il membro dell'istanza Same alla tua sindacata discriminata, che prima deriva la custodia specifica dell'Unione dall'istanza self e quindi costruisce una nuova istanza con lo stesso caso dell'Unione, ma ora popolata con 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
.

Ora applicandolo al valore lowPrice sotto

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

Otterrai highPrice : Currency = Euro 200

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top