La copie d'une union de cas, mais avec une valeur différente en F#
-
13-12-2019 - |
Question
En F#, je veux construire une instance (terminologie correcte?) d'une discrimination union, sur la base d'une instance existante.Exemple:
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 *)
Ce code pourrait-je insérer à la place du commentaire à créer cet effet?
La solution
vous pourriez faire
let highPrice =
let n = 200
match lowPrice with
| Dollar _ -> Dollar n
| Euro _ -> Euro n
Mais les unités de mesure sont probablement meilleures.
Modifier
Alternativement, vous voulez peut-être
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)
Autres conseils
Je pense que pour ce genre de problème, il est plus approprié d'utiliser des unités de mesure - quelque chose comme
[<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 fonction de conversion est un peu délicate mais elle fera ce que vous voulez
Vous pouvez faire de nouveaux cas de l'union des valeurs basées sur la valeur existante de la même union de cas à l'aide de la Réflexion.Pour cela, il suffit d'ajouter le membre de l'instance Same
pour votre union discriminée, qui dérive de l'union spécifique de cas à partir de l'instance self
et puis construit une nouvelle instance par le même syndicat, mais maintenant rempli avec 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
Maintenant, en l'appliquant à lowPrice
la valeur ci-dessous
let lowPrice = Euro(100)
let highPrice = lowPrice.Same 200
vous obtiendrez highPrice : Currency = Euro 200