在Swift中是否可以要求关联类型符合相关类型的关联协议?

问题描述 投票:3回答:2

我试图(基本上没有理由)制定一个描述类别理论类别的协议。我试图想出这样的东西。

protocol Category {
    associatedtype Object: Protocol
}
protocol Hom {
    associatedtype C: Category
    associatedtype Source: C.Object
    associatedtype Target: C.Object
}

特别是,我希望每个Hom类型都有一个关联的类别C和一个相关的Source和Target类型,它们都是该类别中的对象。因此,我已经将Object协议与每个Category相关联,并且已经尝试使Hom的Source和Target符合相应Category的Object协议。上面的代码无法编译

Type 'Self.Source' constrained to non-protocol, non-class type 'Self.C.Object'

这个错误至少不清楚,因为C.Object被声明为协议。有什么方法可以解决这个问题吗?

编辑:

正如Rob指出的那样,代码本身没有多大意义。协议是来自ObjC的特定类,并不是描述协议的类型。此外,没有描述所有协议的类型,因为协议本身不能符合协议,因为它们只是对其他类型的要求。我正在寻找的是一种元类型,Any.Protocol,Sequence.Protocol等都是其实例。

我将详细介绍我想要描述的是什么样的结构。

类别是Object类型和Object的每对实例之间的同态类型。对于Object,A和B的两个实例,同态的类型通常写为Hom(A,B),但我会将Hom<A,B>写成Swiftier。类别然后配备有签名<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的目标或codomain。

类型本身就是一个类别,其中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 GroupRingHom<A,B> where A: Ring, B: Ring(A) -> B一起使用因为每一个都配备了正确的组成。

这可能是不可能的,我愿意接受。如果这个不同,请告诉我,它应该作为一个单独的问题提出。

swift swift-protocols associated-types
2个回答
1
投票

DG

在swift中,您不能将协议关联类型用作关联类型,因为它未定义类型。

关联类型只能用作类型的约束,如下所示:

protocol Category {
    associatedtype Object1:Equatable
}

class Homs:Category{
    typealias Object1 = Int

    func sum(element:Object1){

        print(element+element)
    }
}

或者像这样

protocol Category {
    associatedtype Object1: Equatable
}

protocol Homs {
    associatedtype Cat:Category
    associatedtype Source: Category where Source.Object1 == Cat.Object1
    associatedtype Target: Category where Target.Object1 == Cat.Object1
}

您的代码无法编译的原因是,您的关联类型Target被约束为实现协议的associatedType(未定义)。有人需要先定义它才能用作约束。

解决问题的方法是生成泛型类。我们来看看:

protocol Category {
    associatedtype Object1: Equatable
}

class Homs<Cat:Category,Source,Target> where Cat.Object1 == Source && Cat.Object1 == Target.Object1{

}

另一种方法可以是创建一个通用的Category类,以及一个类别为Class类,类,Class,Source和Target符合Type的协议:

class Category<T>{
}

protocol Homs {
    associatedtype ObjectType
    associatedtype Cat:Category<ObjectType>
    associatedtype Source where Source == ObjectType
    associatedtype Target where Target == ObjectType
}

像第二个例子:

protocol Category {
    associatedtype Object1: Equatable
}

protocol Homs {
    associatedtype Cat:Category
    associatedtype Source: Category where Source.Object1 == Cat.Object1
    associatedtype Target: Category where Target.Object1 == Cat.Object1
}

请记住,您不能将具有关联类型的协议用作关联类型的类型约束,也不能将其用作变量或常量的类型,首先需要定义关联类型。

我希望我帮助过你。


1
投票
associatedtype Object: Protocol

这条线并不意味着你的意思。 Protocol不是Swift的一部分。它是ObjC运行时的一部分。 (这是一个非常令人困惑的导入。)

但即使它确实意味着,我也不相信它会对你有所帮助。重要的是要意识到在Swift中,协议不符合协议,而具有相关类型的协议不是类型。它们是对类型的限制。这往往会蔓延到各处,让人们大吃一惊。

我怀疑你是想要按照这些方式对事物进行建模(注意我的类别理论很弱,所以如果我在点使用错误的术语,请原谅我)。

我们想要达到一个可以说“类别包含对象集合和这些对象之间的箭头集合”的点。为了实现这一目标,我想我们想要从通用箭头开始:

protocol Arrow {
    associatedtype Source
    associatedtype Target
    var apply: (Source) -> Target { get }
}

同态是一种映射回自己类型的箭头。

protocol Homomorphism: Arrow where Source == Target {
    typealias Object = Source
}

有了它,我们可以表达一个类别:

protocol Category {
    associatedtype Object
    associatedtype Arrow: Homomorphism where Arrow.Object == Object
}

我想谈谈整数和函数的类别(我认为这是一个合适的类别)。所以首先我需要功能。

struct Function<Source, Target>: Arrow {
    let apply: (Source) -> Target
}

extension Function: Homomorphism where Source == Target {}

然后我可以声明类别。

struct Integers: Category {
    typealias Object = Int
    typealias Arrow = Function<Int, Int>
}

并创造一种态射。

let increment = Function(apply: { (x: Int) in x + 1 })

我认为这有点像你正在寻找的方向。

© www.soinside.com 2019 - 2024. All rights reserved.