协变序列

时间:2015-11-26 04:43:20

标签: generics f#

我想创建一个F#seq并确保每个元素的记录类型SelctionDescriptor<'a>适用于某些任意类型'a。我知道如何做这个OOP样式:在抽象类上定义seq,然后从中继承泛型类。但是如何做到这种功能风格?

我想要一个协变seq,其中每个元素可能是不同的类型。

1 个答案:

答案 0 :(得分:1)

正如您目前所描述的那样,除非'a属于常规类型,否则在任何范例中我都看不到类型安全的解决方案。正如您在问题中所提到的,您可以使用非泛型接口或抽象基类,但这种方法可能会导致您在某种程度上导致类型测试和不安全转换的路径 - 这绝对不是一个有利的选择。 / p>

如果您可以重构您的描述符,那么其他选项可能会变得可用。为了支持集合中的各种不同的东西,F#实际上打开了一些与C#相比的选项,前提是您可以提前指定使用受歧视的联合的可能选项。

考虑到你有一系列可能是float或int的选择描述符,你可以创建:

type SelectionDescriptor =
    |SelectionDescriptorInt of int
    |SelectionDescriptorFloat of float

作为列表的示例:

let test = 
    [SelectionDescriptorInt 3; SelectionDescriptorFloat 7.0; 
     SelectionDescriptorFloat 19.7; SelectionDescriptorInt 0 ]

然后,当您检查结果时,您可以对每个元素执行模式匹配。这不会影响解决方案的类型安全性,如果我们的检查并非详尽无遗,编译器会发出警告。

注意:如果不同项的结构是常规的,那么使用这种方法将是非常不理想的,即如果你有int,float,int float等,你会好得多。使用seq<int*float>或其他等效的结构化类型。