Geeat solution! Thanks to Nicola for posting it! > Am 14.05.2016 um 16:35 schrieb Matthew Johnson via swift-evolution > <[email protected]>: > > >> On May 14, 2016, at 12:55 AM, Nicola Salmoria via swift-evolution >> <[email protected]> wrote: >> >> Matthew Johnson via swift-evolution <swift-evolution@...> writes: >> >>> I agree it’s a bit tricky. But that’s better than not possible at all. >> You just need a typealias and a same type constraint to make this work as >> expected / desired: >>> >>> >>> protocol Makable { >>> >>> typealias RootMakable = StaticSelf >>> static func make(value: Int) -> StaticSelf >>> } >>> >>> func makeWithZero<T: Makable where T == T.RootMakable>(x: Int) -> T { >>> return T.make(value: 0) // works now >>> } >>> >>> >>> Now that we have a typealias we can refer to the binding of StaticSelf and >> constrain it as necessary for whatever purpose we have in mind. In some >> cases that will be a same type constraint so that our code works properly >> with class clusters. I don’t have concrete examples of other use cases but >> can imagine use cases constraining the typealias to a protocol, for example. >> >> You can do that today: >> >> protocol Makable { >> associatedtype MadeType >> static func make(value: Int) -> MadeType >> } >> >> func makeWithZero<T: Makable where T == T.MadeType>(x: Int) -> T { >> return T.make(value: 0) >> } >> >> You can't currently constrain MadeType to be the same as the conforming >> type, but, does it matter? What kind of extra guarantees would that give, >> since you need to add the extra constraint anyway in generic code? > > Wow, this is pretty cool. Thank you very much for pointing this out Nicola! > > I haven’t seen this approach to solving the problem. Given the amount of > discussion this problem has received I am surprised nobody has shared this > solution yet. I just checked in Xcode 7.3 and it works there. It isn’t > dependent on any pre-release features. > > Instead of using StaticSelf under the current proposal: > > protocol StringInitializable { > static func initializeWith(string: String) -> StaticSelf > } > > We just add an associatedtype defaulted to Self: > > protocol StringInitializable { > associatedtype Initialized = Self // where Self: Initialized > static func initializeWith(string: String) -> Initialized > } > > extension NSURL: StringInitializable { > static func initializeWith(string: String) -> NSURL { > return NSURL() > } > } > > func makeWith<T: StringInitializable where T == T.Initialized>(string: > String) -> T { > return T.initializeWith(string: string) > } > > There are two minor downsides to this approach: > > 1. You can’t copy and paste the method signature. > 2. You can theoretically conform a type completely unrelated to `Initialized` > to the protocol, thus violating the semantics. > > I think we can live with these downsides. Maybe the `Self: Initialized` will > be possible someday. That would be pretty close to StaticSelf. The only > difference would be that subclasses still have flexibility to override with > their own type. > > Now that a reasonable way to do this with existing language features has been > identified I will withdraw this proposal. If this approach doesn’t address > use cases others have in mind for StaticSelf please speak up! > > Doug, if you’re reading this, does the `where Self: Initialized` (i.e. > arbitrary subclass constraints) fall into the scope of your “completing > generics” manifesto? This is a concrete use case that would utilize subclass > constraints.
+1 for being able to constrain the generic type. I've been missing that in my little graph library. -Thorsten > > -Matthew > > >> >> Nicola >> _______________________________________________ >> swift-evolution mailing list >> [email protected] >> https://lists.swift.org/mailman/listinfo/swift-evolution > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
