Say you have:
type A = A of string
type B = B of string
type C = C of string
let a = A "hello"
let b = B "world"
let c = C "!"
There are many ways to extract these values, here are some of them:
Individual unpackers
let getValueA (A v) = v
let getValueB (B v) = v
let getValueC (C v) = v
let valueOfA = getValueA a
let valueOfB = getValueB b
let valueOfC = getValueC c
Method overload
type T =
static member getValue (A v) = v
static member getValue (B v) = v
static member getValue (C v) = v
let valueOfA = T.getValue a
let valueOfB = T.getValue b
let valueOfC = T.getValue c
Function overload
type GetValue = GetValue with
static member ($) (GetValue, (A v)) = v
static member ($) (GetValue, (B v)) = v
static member ($) (GetValue, (C v)) = v
let inline getValue x : string = GetValue $ x
let valueOfA = getValue a
let valueOfB = getValue b
let valueOfC = getValue c
Reflection
open Microsoft.FSharp.Reflection
let getValue a =
FSharpValue.GetUnionFields (a, a.GetType())
|> snd
|> Seq.head
:?> string
let valueOfA = getValue a
let valueOfB = getValue b
let valueOfC = getValue c
Redesign your DU
type A = A
type B = B
type C = C
type MyDU<'a> = MyDU of 'a * string
let a = MyDU (A, "hello")
let b = MyDU (B, "world")
let c = MyDU (C, "!" )
let getValue (MyDU (_, v)) = v
let valueOfA = getValue a
let valueOfB = getValue b
Redesign with Interfaces
type IWrapped<'a> =
abstract getValue: 'a
type A = A of string with interface IWrapped<string> with member t.getValue = let (A x) = t in x
type B = B of string with interface IWrapped<string> with member t.getValue = let (B x) = t in x
type C = C of string with interface IWrapped<string> with member t.getValue = let (C x) = t in x
let valueOfA = (a :> IWrapped<string>).getValue
source
share