> On 12 Mar 2017, at 08:50, Xiaodi Wu <[email protected]> wrote:
>
> On Sun, Mar 12, 2017 at 1:39 AM, Karl Wagner <[email protected]
> <mailto:[email protected]>> wrote:
>
>> On 12 Mar 2017, at 08:21, Xiaodi Wu <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> Sorry, I'm confused. The following works:
>>
>> ```
>> protocol Promise {
>> associatedtype Result
>> }
>>
>> protocol Scanner {
>> associatedtype ScannerPromise : Promise
>> func frobnicate<T>(_: T) -> ScannerPromise
>> where ScannerPromise.Result == T
>> }
>> ```
>>
>> Why does it matter if `ScannerPromise` is generic or not?
>>
>
> That’s some pretty strange syntax. I admit I didn’t even try that.
> ScannerPromise would necessarily have to be generic in this context, because
> I want to bind one of its associated types to a generic parameter from a
> function. There is no way a non-generic type could do that.
>
> That said, even though the compiler accepts your code, it doesn’t seem to
> actually work:
>
> protocol Promise {
> associatedtype Result
> func await() -> Result
> }
>
> protocol Scanner {
> associatedtype ScannerPromise : Promise
> func frobnicate<T>(_: T) -> ScannerPromise
> where ScannerPromise.Result == T
> }
>
> func use<S: Scanner, T>(_ s: S, _ t: T) -> T {
> return s.frobnicate(t).await()
> }
>
>
> 3.0.2: Segfault
>
> 3.1:
>
> error: repl.swift:13:14: error: cannot invoke 'frobnicate' with an argument
> list of type '(T)'
> return s.frobnicate(t).await()
> ^
>
> repl.swift:13:14: note: expected an argument list of type '(T)'
> return s.frobnicate(t).await()
>
> That's because your `T` in `use` has no relationship with your `T` in
> `protocol Scanner`; you just happen to have chosen the same letter of the
> alphabet. This becomes clear if you rename:
>
> ```
> func use<S: Scanner, U>(_ s: S, _ t: U) -> U {
> return s.frobnicate(t).await()
> }
>
> // cannot invoke 'frobnicate' with an argument list of type '(U)'
> // expected an argument list of type '(T)'
> ```
>
> However, this works:
>
> ```
> func use<S: Scanner, T>(_ s: S, _ t: T) -> T
> where S.ScannerPromise.Result == T {
> return s.frobnicate(t).await()
> }
> ```
>
> ...or just this:
>
> ```
> func use<S: Scanner>(
> _ s: S, _ t: S.ScannerPromise.Result
> ) -> S.ScannerPromise.Result {
> return s.frobnicate(t).await()
> }
> ```
>
> - Karl
>
I’m pretty sure that the compiler is interpreting the constraint with “reverse
emphasis”, so to speak. That is:
func frobnicate<T>(_: T) -> ScannerPromise where ScannerPromise.Result == T
becomes
func frobnicate<T>(_: T) -> ScannerPromise where T == ScannerPromise.Result
becomes
func frobnicate(_: ScannerPromise.Result) -> ScannerPromise
which is why you can’t invoke it with a generic ’T’
- Karl
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution