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

jbe*_*eko 4 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]
Run Code Online (Sandbox Code Playgroud)

Tom*_*cek 6

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

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

type Value = 
  | Float of Holder<float>
  | Int of Holder<int>
Run Code Online (Sandbox Code Playgroud)

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

let list = [Int intVal; Float floatVal]
Run Code Online (Sandbox Code Playgroud)

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

type IHolder = 
  abstract Name : string

type Holder<'data> = 
  { Data : 'data
    Name : string }
  interface IHolder with
    member x.Name = x.Name
Run Code Online (Sandbox Code Playgroud)

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

let list = [intVal :> IHolder; floatVal :> IHolder]
for h in list do printfn "%s" h.Name
Run Code Online (Sandbox Code Playgroud)

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