[swift-evolution] [Manifesto] Completing Generics

Brent Royal-Gordon brent at architechies.com
Wed Aug 3 04:09:50 CDT 2016

> On Aug 2, 2016, at 7:58 AM, Patrick Lind via swift-evolution <swift-evolution at swift.org> wrote:
> http://stackoverflow.com/questions/38619660/is-it-possible-to-pass-generic-protocols-into-a-constructor-for-proper-dependenc

I *think* that the specific feature you're looking for here is usually called "enhanced existentials". This would have a different syntax—something like `RepositoryProtocol where Object == Zombie`—but would do basically the same thing.

The way to work around this in Swift 2 or 3 is to manually write a type-erasing wrapper:

	// Effectively a constructor of AnyRepository.
	public func anyRepository<Repository: RepositoryProtocol>(_ repository: Repository) -> AnyRepository<Repository.Object> {
		// Don't double-wrap
		if let repo = repository as? AnyRepository<Repository.Object> {
			return repo
		return ConcreteAnyRepository(repository: repository)
	// This is the public face of the wrapper. It's actually abstract. Since it doesn't have the 
	// RepositoryProtocol as a parameter, it "erases" the repository's type.
	public class AnyRepository<Object>: RepositoryProtocol {
		private init() {}
		public var items: Array<Object> {
			get { fatalError("abstract") }
			set { fatalError("abstract") }
		public func insert(_ object: Object) {
		public func deleteAll() {
	// All instances of AnyRepository will actually belong to this concrete subclass, which 
	// *does* have the specific RepositoryProtocol as a parameter.
	private class ConcreteAnyRepository<Repository: RepositoryProtocol>: AnyRepository<Repository.Object> {
		private let repository: Repository
		override var items: Array<Object> {
			get { return repository.items }
			set { repository.items = newValue }
		override func insert(_ object: Object) {
		override func deleteAll() {

And then your ZombieServiceProtocol can look like:

	protocol ZombieServiceProtocol {
	    func fetchZombies()
	    var zombieRepository: AnyRepository<Zombie> { get set }

Brent Royal-Gordon

More information about the swift-evolution mailing list