如何创建包含具有公共超类的对象的F#列表?

Jul*_*les 2 wpf f# types list supertype

我有两个功能,水平和垂直,用于布局控件.他们的工作方式如下:

let verticalList = vertical [new TextBlock(Text = "one"); 
                             new TextBlock(Text = "two"); 
                             new TextBlock(Text = "three")]
Run Code Online (Sandbox Code Playgroud)

现在verticalList是一个垂直显示三个文本块的控件:

one
two
three
Run Code Online (Sandbox Code Playgroud)

以下是定义:

let horizontal controls = 
    let wrap = new WrapPanel() in
    List.iter (wrap.Children.Add >> ignore) controls ;
    wrap

let vertical controls = 
    let stack = new StackPanel() in
    List.iter (stack.Children.Add >> ignore) controls ;
    stack
Run Code Online (Sandbox Code Playgroud)

当我组合不同类型时会出现问题:

let foo = vertical [new TextBlock(Text = "Title"); vertical items]
Run Code Online (Sandbox Code Playgroud)

这抱怨列表中的元素不是同一类型.这是事实,但他们有一个共同的超类型(UIElement).

我知道我可以使用:> UIElement来覆盖列表中的两个项目,但这是一个丑陋的解决方案.F#可以推断出常见的超类型.如果没有,为什么不呢?

如果看起来很漂亮会很棒的

vertical [X; Y; Z]
Run Code Online (Sandbox Code Playgroud)

不必成为

vertical [(X :> UIElement); (Y :> UIElement); (Z :> UIElement)]
Run Code Online (Sandbox Code Playgroud)

Bri*_*ian 5

有几种方法,包括

type Animal() = class end
type Cat() =
    inherit Animal()
type Dog() =
    inherit Animal()
let animals1 : list<Animal> = [upcast new Cat(); upcast new Dog()]
let animals2 = ([upcast new Cat(); upcast new Dog()] : list<Animal>)
let animals3 = [(new Cat() :> Animal); upcast new Dog()]
Run Code Online (Sandbox Code Playgroud)

animals1:在var声明中键入注释,向上转换每个元素

animals2:在列表表达式上键入注释,向上转换每个元素

animals3:第一个元素的显式类型,upcast rest

在F#的未来版本中,上传很可能变得不必要.

(另见http://cs.hubfs.net/forums/thread/9953.aspx,但没有'新'那里.)