Is it possible to use protocols with associated types as opaque return types?

I.e. is it possible to use a return type such as some A where A.B == C?

My hunch is no, but I’d hoped it might be (or could be in the future), given that the original pitch cites LazyMapCollection (with associated type Element) as a compelling example of why opaque types are needed.

Context: I’m building a parsing library that uses function builders to provide a clean syntax for combining parsers, which all conform to a Parser protocol. The simplified code snippet below illustrates the problem:

// ERROR: 'Parsable' requires the types 'MyParsable.S' (aka 'Substring')
// and '(some Parser).S' be equivalent
struct MyParsable: Parsable {
    typealias S = Substring
    var body: some Parser {
        MyParser()
    }
}

struct MyParser: Parser {
    func parse(_ input: Substring) -> (Substring, Character)? {
        var remainingInput = input
        return remainingInput.popFirst().map {
            (remainingInput, $0)
        }
    }
}

protocol Parser {
    associatedtype S : Collection where S.SubSequence == S
    associatedtype R
    func parse(_ input: S) -> (S.SubSequence, R)?
}

protocol Parsable: Parser where P.S == S {
    associatedtype P : Parser
    var body: P { get }
}

extension Parsable {
    func parse(_ input: S) -> (S, P.R)? {
        body.parse(input)
    }
}

I’m trying to find a way to constrain the some Parser return type in MyParsable to make (some Parser).S and MyParsable.S equivalent. Any help will be much appreciated :).

Constraining some Parser is a feature not implemented in the current version of Swift.

1 Like

Good to know, thanks for the response. I wonder if there are any plans to implement this in the future?

For now I’ll probably just use let parser = ... (with type inference, so users of the library don’t have to type out the incredibly complex types of nested parsers).