Swift 4.2: conforming to protocol with generic func?

Consider the following:


import Cocoa

protocol Mark {}

protocol Detector: class {
  func check<M: Mark>(mark: M)
}

enum ColorTint: Mark {
  case red, green, blue
}

class Vision: Detector { // Error: type does not conform to protocol
  func check(mark: ColorTint) {
       switch mark {
            case .red:
                 print("I see reddish")
            case .green:
                 print("I see greenish")
            case .blue:
                 print("I see blueish")
       }
  }
}


I have two protocols, one of which has generic function with parameter constrained to another protocol. In the result I cannot make a type conformant to the protocol with the generic function. Is it even possible?

Accepted Reply

Still, I wonder if it was possible to do with generics.


The answer is NO.


When you declare a prtocol with generic method, without typealias like your Detector:

protocol Detector: class {
    func check<M: Mark>(mark: M)
}


the type conforming to the protocol needs to implement the generic method:

class Vision: Detector {
    func check<M: Mark>(mark: M) {
        print("I see \(mark)ish")
        //...
    }
}


If you have found that you can do it with associated type, it's not a workaround, but the right solution.

Replies

Okay, I was able to work around that by getting rid of the generic protocol function in favour of associated type, which then can be explicitly specified in Vision class.


Still, I wonder if it was possible to do with generics.

Still, I wonder if it was possible to do with generics.


The answer is NO.


When you declare a prtocol with generic method, without typealias like your Detector:

protocol Detector: class {
    func check<M: Mark>(mark: M)
}


the type conforming to the protocol needs to implement the generic method:

class Vision: Detector {
    func check<M: Mark>(mark: M) {
        print("I see \(mark)ish")
        //...
    }
}


If you have found that you can do it with associated type, it's not a workaround, but the right solution.

To be precise I tried to make Vision class implementing generic method, but I couldn't find syntax to make compiler happy. Specifing generic parameter for class and/or method didn't work.


Is there any way to make Vision class from my example work without changing given protocols and enum?
EDIT: With the check function constrained to ColorTint type, of course, not to any Mark.

Is there any way to make Vision class from my example work without changing given protocols and enum?

EDIT: With the check function constrained to ColorTint type, of course, not to any Mark.


I need to repeat NO. When a method declares generic parameters of its own, I mean not using associatedtype,

the type conforming to the method needs to implement the generic method.


You need to modify the protocol, if your `Vision` class implements only a method specific to `ColorTint`.

Thank you for clarifying.

My original idea behind the protocols with generic functions was to have a single class that can conform to two or more specializations of the same protocol. I would just have to provide required 'check' functions specialized for concrete types. Associated types do not allow for that, as a conforming class can be specialised for one type only. So, I will have to resort to using single 'check' function with runtime type matching.