Why can't I use some in protocol requirement as return type

I wanted to use some as a return type inside a protocol, but the compiler wouldn't let me:

protocol Dispatchable {
    associatedtype Message
    var messages: some Collection<Message>  { get }
    
    func dispatch( _ message: Message )
}

But the compiler complains that:

'some' type cannot be the return type of a protocol requirement; did you mean to add an associated type?

Not sure why this is, since the View protocol in SwiftUI returns in it's body computed property some View

I was able to re-write the protocol and obtained what I want by:

protocol Dispatchable {
    associatedtype Messages: Collection
    var messages: Messages  { get }
    
    func dispatch( _ message: Messages.Element )
}

But I'm still not sure as to why the first method I've used didn't work. And how come, since Collection protocol uses a primary associated type Element I don't have to specify it here.
I guess the associated Element type will be deduced when a class/struct will implement the protocol?

1 Like

See https://github.com/apple/swift-evolution/blob/main/proposals/0244-opaque-result-types.md#restrictions-on-opaque-result-types.

Associated types provide a better way to model the same problem, and the requirements can then be satisfied by a function that produces an opaque result type. (There might be an interesting shorthand feature here, where using some in a protocol requirement implicitly introduces an associated type, but we leave that for future language design to explore.)

1 Like

This would work even if primary associated types didn't exist. You didn't add any constraints to Collection.Element, so a type that conforms to Dispatchable could use any type that conforms to Collection as its Messages type.

But you could've added constraints to Collection.Element. For example:

associatedtype Messages: Collection where Messages.Element: Equatable

or

associatedtype Messages: Collection where Messages.Element == String

Yes.

I think it should be allowed (thread).

In this case, you could do the same thing with an associated type so it's just a shorthand (not that shorthands are not useful - they are!). There are other situations, though, where you cannot express the value of an associated type (e.g. because it depends on another generic context, or availability), and opaque types could unblock those model designs.

1 Like