我想写的是:
type A() =
interface IX with ...
interface IY with ...
type B() =
interface IX with ...
interface IY with ...
let mk t : 'T when 'T :> IX and 'T :> IY =
match t with
| Choice1 -> new A()
| Choice2 -> new B()
Run Code Online (Sandbox Code Playgroud)
注意mk的返回类型的类型约束.虽然它没有编译,编译器抱怨它不能将A和B转换为'T.
约束是好的,但问题是,有没有类型会满足约束,这将是两者的超类型A和B.
该match结构需要从两个分支的返还相同种类,所以你需要向上转型添加(:>)以某种类型使得改建工程两个分支.类型可以是IX或IY,但不满足约束.
这将是可能的,只有.NET允许你写的东西像IX+IY这将意味着同时实现了接口的类型.然后你也可以使用这种类型的值,例如:
let (a:IX+IY) = new A() // This isn't supported
Run Code Online (Sandbox Code Playgroud)
我认为最好的解决方案是简单地返回一个IX * IY包含两次相同实例的元组,但表示为不同的类型.在这里你写的这个constriant非常有用:
// Type: 'a -> IX * IY when 'a :> IX and 'a :> IY
let asTuple a = (a :> IX, a :> IY)
let mk t =
match t with
| Choice1Of2() -> new A() |> asTuple
| Choice2Of2() -> new B() |> asTuple
Run Code Online (Sandbox Code Playgroud)
如果你控制的类型A和B,那么最简单的解决办法是确定
type IXY =
inherit IX
inherit IY
Run Code Online (Sandbox Code Playgroud)
然后拥有A并B继承IXY,并且mk只返回一个IXY而不是泛型类型(即使没有约束,它也无论如何都没有意义).
| 归档时间: |
|
| 查看次数: |
414 次 |
| 最近记录: |