Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 从并集大小写中提取值_F# - Fatal编程技术网

F# 从并集大小写中提取值

F# 从并集大小写中提取值,f#,F#,在一个Fsharp应用程序中,我定义了几个联合案例类型 type A = A of String type B = B of String type C = C of String 我想定义一个函数来从union case实例中提取值 let getValue( ctor: String-> 'a) = ...implementation here 有没有办法完成这样的任务? 谢谢。假设您有: type A = A of string type B = B of string

在一个Fsharp应用程序中,我定义了几个联合案例类型

type A = A of String
type B = B of String
type C = C of String
我想定义一个函数来从union case实例中提取值

let getValue( ctor: String-> 'a) = 
   ...implementation here
有没有办法完成这样的任务? 谢谢。

假设您有:

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 "!"
提取这些值的方法有很多,以下是一些:

单个展开器

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
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
方法重载

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
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
功能过载

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
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
反射

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
重新设计您的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
类型A=A
B型=B型
C型=C型
键入MyDU.IWrapped).getValue

我看不到一种明显的方法可以不经过反射就做到这一点,尽管可能存在一种方法。我认为最近也有类似的方法,否则您可以扩展示例代码吗?字符串的类型A不是有效的F#代码。@Gustavo我已更正了问题中的语法错误。我想做的是不要使用歧视工会。谢谢你的回答。我一直在寻找一个没有很多模式匹配的函数来从不同类型中提取值。看来反射是唯一的解决方案?我有点惊讶,F#不支持这个看似简单的场景。不,它不支持,而且有道理,DU可以用多种方式定义,而不仅仅是一个大小写、单个字符串参数。如果你所有的DU都有相同的结构,为什么不改变你的设计来反映这一点呢?看到更新了。我在关注这个特殊的博客,只是觉得有比接口更好的方法来实现“值”功能。在这种情况下,你让他们实现一个接口。继续阅读博客,它解释了如何实现接口。我确实看到了实现接口是如何工作的,但这是很多重复的代码。