0

In Swift I have a protocol that represents an object that wraps a value. I'd like to add a mapping function to that protocol that indicates that some mapping function will be applied to that value to return another instance of that protocol. My protocol looks like this so far:

protocol Foo {

    typealias Value

    func flatMap<T>(map: (Value) -> T) -> Self

...

Basically I want flatMap to take a block which is passed in Value and returns T and I want the "Self" that's returned to be specialized on T. This isn't quite right though because Self is the type of the protocol. Really what I want to return is "Self" but I can't do that obviously.

JPC
  • 8,096
  • 22
  • 77
  • 110
  • 1
    This isn't possible in Swift. It's possible that `Foo` will be implemented by a non-final class, and if that happens, the compiler can't prove that you will (or even can) return exactly `Self`. Your specific goal is doubly-impossible because it requires a higher-kinded type. You can't have something of type `Array` in Swift. You *have* to constrain it to a specific type instance such as `Array`. If Swift had higher-kinded types, then you could talk about `Array` (or other generic types) in the abstract, but you can't today. – Rob Napier Sep 13 '16 at 16:25
  • Thanks for the response. Is there a close enough? Is there where "type-erasure" might come in handy? – JPC Sep 13 '16 at 16:35
  • Using type erasure, your `flatMap` could return an `AnyFoo` struct that conforms to `Foo` (or any other protocol you like). But you could only call `Foo` methods on it and you can't get the original type back out of a type eraser, even if you know what type it is. (They can't be `as` casted. They're not protocols, they're structs.) See http://robnapier.net/erasure – Rob Napier Sep 13 '16 at 16:44

0 Answers0