f# - 如何在 F# 中声明返回满足多个约束的类型的泛型函数?

标签 f# generics

我想写的:

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()

注意 mk 的返回类型的类型约束。虽然它没有编译,但编译器提示它不能将 A 和 B 转换为 'T。

最佳答案

约束没问题,但问题是没有类型可以满足约束,并且这将是 A 的父类(super class)型。和 B .
match构造需要从两个分支返回相同的类型,因此您需要将向上转换 ( :> ) 添加到某种类型,以便转换适用于两个分支。类型可以是 IXIY ,但这不会满足约束。

仅当 .NET 允许您编写类似 IX+IY 的内容时,这才有可能。这意味着实现两个接口(interface)的类型。然后你也可以使用这种类型的值,例如:

let (a:IX+IY) = new A()  // This isn't supported

我认为最好的解决方案是简单地返回一个元组 IX * IY包含两次相同的实例,但表示为不同的类型。在这里,您编写的约束可能非常有用:
// 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

关于f# - 如何在 F# 中声明返回满足多个约束的类型的泛型函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4335866/

相关文章:

java - 扩展类并实现接口(interface)的通用类

scala - F# 的异步工作流的 Scala 等价物是什么?

f# - 如何设计一个功能风格的可插拔系统?

generics - 比较 Kotlin 中的可比对象列表

java - 如何使用不同的类作为方法中的参数

java - 复制不同类型的HashMap

c# - .NET//vs///注释约定

.net - 在 F# 中使用 LINQ?

f# - 在 F# 中执行 tryMax 和 tryMin 的最佳方法?

c# - 从类型参数创建继承类