Can I specify that an associatedtype is a function?

As I mentioned above, what I have now is something like this:

public protocol CallType: Sendable {
  associatedtype Callback: Sendable
}

public enum SyncCall: CallType {
  public typealias Callback = @Sendable () throws -> Void
}
public enum AsyncCall: CallType {
  public typealias Callback = @Sendable () async throws -> Void
}

struct Container<Call: CallType> {
  let description: String
  let block: Call.Callback

  init(_ description: String, executing block: @escaping Call.Callback)
       where Call == SyncCall {
    self.description = description
    self.block = block
  }
  init(_ description: String, executing block: @escaping Call.Callback)
       where Call == AsyncCall {
    self.description = description
    self.block = block
  }
}

@escaping is required there since I'm storing the callback, but I can only use it if the type I'm talking about is known by the compiler to be a function type. Thus I have to have two copies of the initializer, differing only in the where clause, so the compiler knows I'm talking about SyncCall.Callback and AsyncCall.Callback which are function types.

But if we had a built-in protocol for that - let's pretend it's called FunctionType - then I'm thinking I could do it this way:

public protocol CallType: Sendable {
  associatedtype Callback: Sendable, FunctionType
}

// same SyncCall and AsyncCall as above

struct Container<Call: CallType> {
  let description: String
  let block: Call.Callback

  // Just one version of the initializer because Call.Callback conforms
  // to FunctionType and so @escaping can be applied.
  init(_ description: String, executing block: @escaping Call.Callback) {
    self.description = description
    self.block = block
  }
}
1 Like