从工会案例中提取价值

Wei*_* Ma 7 f#

在Fsharp应用程序中,我已将几个联合案例类型定义为

type A = A of String
type B = B of String
type C = C of String
Run Code Online (Sandbox Code Playgroud)

我想定义一个函数来从union case实例中提取值.

let getValue( ctor: String-> 'a) = 
   ...implementation here
Run Code Online (Sandbox Code Playgroud)

反正有没有完成这样的任务?谢谢.

Gus*_*Gus 11

假设你有:

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 "!"
Run Code Online (Sandbox Code Playgroud)

有很多方法可以提取这些值,这里有一些:

个别打包者

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
Run Code Online (Sandbox Code Playgroud)

方法过载

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
Run Code Online (Sandbox Code Playgroud)

功能过载

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
Run Code Online (Sandbox Code Playgroud)

反射

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
Run Code Online (Sandbox Code Playgroud)

重新设计你的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
Run Code Online (Sandbox Code Playgroud)

使用接口重新设计

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
Run Code Online (Sandbox Code Playgroud)

  • 不,它没有,但这是有道理的,DU 可以通过多种方式定义,而不仅仅是单一情况、单一字符串参数。如果您的所有 DU 始终具有相同的结构,为什么不更改您的设计来反映这一点呢?请参阅更新。 (2认同)