I want add setter property to discriminated unions, how I should to do it?
fe:
type Factor =
| Value of Object
| Range of String
let mutable myProperty = 123
member this.MyProperty
with get() = myProperty
and set(value) = myProperty <- value
Here's how I might approach it:
type Value = { value: obj; mutable MyProperty: int }
type Range = { range: string; mutable MyProperty: int }
type Factor =
| Value of Value
| Range of Range
member this.MyProperty
with get() =
match this with
| Value { MyProperty=myProperty }
| Range { MyProperty=myProperty } -> myProperty
and set(myProperty) =
match this with
| Value x -> x.MyProperty <- myProperty
| Range x -> x.MyProperty <- myProperty
and use it like so:
let v = Value {value="hi":>obj ; MyProperty=0 }
v.MyProperty <- 2
match v with
| Value { value=value } as record ->
printfn "Value of value=%A with MyProperty=%i" value record.MyProperty
| _ ->
printfn "etc."
I've used this technique in a similar scenario to yours with happy results in FsEye's watch model: http://code.google.com/p/fseye/source/browse/tags/2.0.0-beta1/FsEye/WatchModel.fs .
Why not use a class and an active pattern:
type _Factor =
| Value_ of obj
| Range_ of string
type Factor(arg:_Factor) =
let mutable myProperty = 123
member this._DU = arg
member this.MyProperty
with get() = myProperty
and set(value) = myProperty <- value
let (|Value|Range|) (arg:Factor) =
match arg._DU with
|Value_(t) -> Value(t)
|Range_(t) -> Range(t)
This will obviously be significantly slower, but it allows you to do what you want
I'm not too familiar with F# yet, but I suppose you can't do this, it doesn't make any sense. Discriminated Unions as it can be seen from their name are unions. They represent some kind of a choice. And you're trying to incorporate some state into it. What're you trying to achieve? What's the use case?
Perhaps everything you need is to add additional "parameter" to your DU, ie if you have
type DU =
| A of int
| B of string
and you want to add setter of int type, then you can extend DU in such a way:
type DU =
| A of int * int
| B of string * int
member x.Set i =
match x with
| A(a1, a2) -> A(a1, i)
| B(b1, b2) -> B(b1, i)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.