具有混合参数化类型的列表

时间:2016-09-03 15:54:59

标签: f#

给定带有类型参数的类型,是否可以创建包含具有混合具体类型的值的列表?请参阅下面的代码。一切正常,直到我尝试创建list2,其中一些元素具有数据的int,而其他元素具有浮点数。有没有办法做到这一点?我在list3中的尝试无法编译。

type Holder<'data> = {
    Data : 'data
    Name : String
}

let intVal =
    {Data = 23;
    Name = "Bill"}

let intVal2 =
    {Data = 29;
    Name = "Cindy"}

let floatVal =
    {Data = 23.0;
    Name = "John"}

let list1 = [intVal; intVal2]
let list2 = [intVal; floatVal]
let list3 : Holder<'a> list = [intVal; floatVal]

1 个答案:

答案 0 :(得分:6)

创建列表时,列表的元素必须属于同一类型。这意味着您无法创建包含Holder<int>Holder<float>的列表。

如果要创建混合类型列表,可以定义区分联合:

type Value = 
  | Float of Holder<float>
  | Int of Holder<int>

使用以下方法创建Value类型的列表:

let list = [Int intVal; Float floatVal]

或者,您可以定义一个接口,捕获两者之间的共性(此处为共享Name属性),并创建接口类型值的列表。在您的示例中,这将如下所示:

type IHolder = 
  abstract Name : string

type Holder<'data> = 
  { Data : 'data
    Name : string }
  interface IHolder with
    member x.Name = x.Name

创建转换为Holder<_>个实例的IHolder值列表:

let list = [intVal :> IHolder; floatVal :> IHolder]
for h in list do printfn "%s" h.Name

界面选项可让您轻松打印所有名称,但却难以访问数据。使用区分联合,类型更复杂,但您可以在其上进行模式匹配以获取值。