Я пытаюсь (по существу без причины) составить протокол, который описывает категории из теории категорий. Я пытался придумать что-то вроде этого.
protocol Category {
associatedtype Object: Protocol
}
protocol Hom {
associatedtype C: Category
associatedtype Source: C.Object
associatedtype Target: C.Object
}
В частности, я хочу, чтобы у каждого типа Hom была связанная категория C и связанный тип Source и Target, которые оба являются объектами в этой категории. Следовательно, я связал протокол объекта с каждой категорией и попытался привести в соответствие источник и цель Hom с протоколом объекта для соответствующей категории. Приведенный выше код не компилируется с
Type 'Self.Source' constrained to non-protocol, non-class type 'Self.C.Object'
Эта ошибка как минимум неясна, поскольку C.Object объявлен протоколом. Можно ли как-то обойти эту проблему?
Edit:
Как указал Роб, код как таковой не имеет особого смысла. Протокол - это особый класс из 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.
Сами типы являются категорией, в которой 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
, поскольку каждый из них снабжен правильным видом композиции.
Может быть просто невозможно сделать это, что я был бы готов принять. Пожалуйста, дайте мне знать, если это достаточно отличается, чтобы его нужно было задать в качестве отдельного вопроса.