【发布时间】:2019-03-23 05:46:07
【问题描述】:
我正在尝试(基本上没有理由)制定一个描述类别理论的类别的协议。我试图想出这样的东西。
protocol Category {
associatedtype Object: Protocol
}
protocol Hom {
associatedtype C: Category
associatedtype Source: C.Object
associatedtype Target: C.Object
}
特别是,我希望每个 Hom 类型都有一个关联的类别 C 以及一个关联的 Source 和 Target 类型,它们都是该类别中的对象。因此,我为每个 Category 关联了一个 Object 协议,并试图使 Hom 的 Source 和 Target 符合相应 Category 的 Object 协议。上面的代码编译失败
Type 'Self.Source' constrained to non-protocol, non-class type 'Self.C.Object'
这个错误至少不清楚,因为 C.Object 被声明为协议。有什么办法可以解决这个问题吗?
编辑:
正如 Rob 所指出的,按原样编写的代码没有多大意义。 Protocol 是 ObjC 的一个特殊类,不是描述协议的类型。此外,没有描述所有协议的类型,因为协议本身不能符合协议,因为它们只是对其他类型的要求。我正在寻找的是 Any.Protocol、Sequence.Protocol 等都是其实例的元类型。
我将更详细地说明我要描述的构造类型。
一个类别是一个对象类型和一个对象的每对实例之间的同态类型。对于Object的两个实例,A和B,同态的类型一般写成Hom(A,B),但我会写Hom<A,B>更快捷。然后类别配备具有签名<A: Object, B: Object, C: Object>(_ f: Hom<A,B>, _ g: Hom<B,C>) -> Hom<A,C> 的组合。
如果 f 是 Hom<A,B> 的一个实例,则 A 称为 f 的源或域,B 称为 f 的目标或共域。
类型本身就是一个类别,其中 Object 是所有类型的元类型,Hom<A,B> = (A) -> B。
在 Swift 中分类很难的主要原因是 Swift 没有依赖类型。无法描述对象类型为 Int 的类别,因为无法拥有类型 Hom<0,0>。但是,如果要求 Object 类型是元类型,那么突然间Hom<A,B> 对类型系统进行描述是一件有意义的事情,因为元类型的实例是一种类型(我认为),它可以是一个泛型参数。这就是我试图通过设置 Object: Protocol 来描述的内容。
在 Swift 中,我真的很想描述
protocol Category {
associatedtype Object: Metatype
associatedtype Hom<A: Object, B: Object>
func compose<A: Object, B: Object, C: Object>(_ f: Hom<A,B>, then g: Hom<B,C>) -> Hom<A,C>
}
但这也不是首发,因为关联类型不能有泛型参数。
在我的用例中,我有一个描述有限生成的阿贝尔群的协议和一个描述有限生成的单位环的协议,我很想编写通用代码,它不关心它是否与 GroupHom<A,B> where A: AbelianGroup, B: Abelian Group 一起使用,RingHom<A,B> where A: Ring, B: Ring,或(A) -> B,因为它们都配备了正确的构图。
这可能是不可能的,我愿意接受。请让我知道这是否足够不同,应该作为一个单独的问题提出。
【问题讨论】:
-
associatedtype Object: Protocol几乎可以肯定没有做你认为它正在做的事情。Protocol不是 Swift 中的类型,在这种情况下,它并不意味着“Swift 协议”。它是您从 ObjC 运行时(可能通过 Foundation)导入的 ObjC 类,其中包含有关 ObjC 协议的元数据。 Swift 等价物是Any.Protocol,但它本身不是协议或类,所以你不能将 Object 约束到它。 -
(而且
Any.Protocol甚至没有真正捕捉到你想说的话,因为其他协议不是Any.Protocol的子类型)
标签: swift swift-protocols associated-types