<div dir="ltr">That will not work since R can be different types depending on T (R == (T, T) for S2 and R == (T, T, T) for S3).<div>I guess Swift would have to support generic associated type for it to work:</div><div><div style="font-size:12.800000190734863px">protocol P {</div><div style="font-size:12.800000190734863px">    associatedtype R&lt;U&gt;</div><div style="font-size:12.800000190734863px">    static func foo&lt;T&gt;(_ v: T) -&gt; R&lt;T&gt;</div><div style="font-size:12.800000190734863px">}<br></div><div style="font-size:12.800000190734863px">struct S2 : P {</div><div style="font-size:12.800000190734863px">    typealias R&lt;U&gt; = (U, U)</div><div style="font-size:12.800000190734863px">    static func foo&lt;T&gt;(_ v: T) -&gt; R&lt;T&gt; {</div><div style="font-size:12.800000190734863px">        return (v, v)</div><div style="font-size:12.800000190734863px">    }</div><div style="font-size:12.800000190734863px">}</div><div style="font-size:12.800000190734863px">struct S3 : P {</div><div style="font-size:12.800000190734863px">    typealias R&lt;U&gt; = (U, U, U)</div><div style="font-size:12.800000190734863px">    static func foo&lt;T&gt;(_ v: T) -&gt; R&lt;T&gt; {</div><div style="font-size:12.800000190734863px">        return (v, v, v)</div><div style="font-size:12.800000190734863px">    }</div><div style="font-size:12.800000190734863px">}</div></div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">But (sadly) according to previous discussions it seems like generic associated types are very much out of scope for Swift 4.</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">PS</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">The generic static func was only a (what I guess is another) failed attempt at a workaround, and what I&#39;m really trying to achieve is something that is perhaps better described like this:</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">protocol VectorCount {</div><div style="font-size:12.800000190734863px">    associatedtype Storage&lt;E&gt;</div><div style="font-size:12.800000190734863px">}</div><div style="font-size:12.800000190734863px">…</div><div style="font-size:12.800000190734863px">enum VectorCount2 : VectorCount {</div><div style="font-size:12.800000190734863px">    typealias Storage&lt;E&gt; = (E, E)</div><div style="font-size:12.800000190734863px">    …</div><div style="font-size:12.800000190734863px">}</div><div style="font-size:12.800000190734863px">enum VectorCount3 : VectorCount {</div><div style="font-size:12.800000190734863px">    typealias Storage&lt;E&gt; = (E, E, E)</div><div style="font-size:12.800000190734863px">    …</div><div style="font-size:12.800000190734863px">}</div><div style="font-size:12.800000190734863px">…</div><div style="font-size:12.800000190734863px">struct Vector&lt;Count: VectorCount, Element&gt; {</div><div style="font-size:12.800000190734863px">    var elements: Count.Storage&lt;Element&gt;</div><div style="font-size:12.800000190734863px">    …</div><div style="font-size:12.800000190734863px">}</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">That is, Vector is a statically allocated array type, with type level Count and Element as type parameters.</div><div style="font-size:12.800000190734863px">I currently have a solution which is based around separate generic vector types for each VectorCountX type, but they are generic only over Element not both Count and Element, like this:</div><div style="font-size:12.800000190734863px">…</div><div style="font-size:12.800000190734863px">protocol VectorProtocol {</div><div style="font-size:12.800000190734863px">    associatedtype Count: VectorCount</div><div style="font-size:12.800000190734863px">    associatedtype Element</div><div style="font-size:12.800000190734863px">    …</div><div style="font-size:12.800000190734863px">}</div><div style="font-size:12.800000190734863px">struct V2&lt;Element&gt; : VectorProtocol {</div><div style="font-size:12.800000190734863px">    typealias Count = VectorCount2</div><div style="font-size:12.800000190734863px">    var elements: (Element, Element)</div><div style="font-size:12.800000190734863px">    …</div><div style="font-size:12.800000190734863px">}</div><div style="font-size:12.800000190734863px">struct V3&lt;Element&gt; : VectorProtocol {</div><div style="font-size:12.800000190734863px">    typealias Count = VectorCount3</div><div style="font-size:12.800000190734863px">    var elements: (Element, Element, Element)</div><div style="font-size:12.800000190734863px">    …</div><div style="font-size:12.800000190734863px">}<br></div><div style="font-size:12.800000190734863px">…</div><div style="font-size:12.800000190734863px">And you can of course also make specific types like eg:</div><div style="font-size:12.800000190734863px">struct RgbaFloatsSrgbGamma : Vector {</div><div style="font-size:12.800000190734863px">    typealias Count = VectorCount4</div><div style="font-size:12.800000190734863px">    typealias Element = Float</div><div style="font-size:12.800000190734863px">    …</div><div style="font-size:12.800000190734863px">}</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">It&#39;s working and it can be written in a way such that the optimizer can do a good job, vectorizing operations on vectors of 4 floats etc. It also makes it possible to write generic Table&lt;Element, Index&gt; where Index is an N-dimensional vector of Int elements, which enables me to write N-dimensional data processing generically, eg a calculating a summed area table for data of any dimension, etc.  But it would be much better to base the vector types around a concept in which both Element and Count are type parameters, and not just Element, ie Vector&lt;Count, Element&gt; rather than V1&lt;Element&gt;, V2&lt;Element&gt;, …</div><div style="font-size:12.800000190734863px"><br></div><div style="font-size:12.800000190734863px">/Jens</div><div style="font-size:12.800000190734863px"><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jul 7, 2017 at 6:49 PM, Slava Pestov <span dir="ltr">&lt;<a href="mailto:spestov@apple.com" target="_blank">spestov@apple.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Try using an associated type for the result of foo():<br>
<br>
protocol P {<br>
  associatedtype R<br>
<br>
  static func foo&lt;T&gt;(_ v: T) -&gt; R<br>
}<br>
<br>
Slava<br>
<div><div class="h5"><br>
&gt; On Jul 7, 2017, at 1:50 AM, Jens Persson via swift-users &lt;<a href="mailto:swift-users@swift.org">swift-users@swift.org</a>&gt; wrote:<br>
&gt;<br>
&gt; protocol P {<br>
&gt;     // …<br>
&gt;     // For example the following will not work:<br>
&gt;     // static func foo&lt;T, R&gt;(_ v: T) -&gt; R<br>
&gt;     // Is there some other way?<br>
&gt;     // …<br>
&gt; }<br>
&gt; struct S2 : P {<br>
&gt;     static func foo&lt;T&gt;(_ v: T) -&gt; (T, T) {<br>
&gt;         return (v, v)<br>
&gt;     }<br>
&gt; }<br>
&gt; struct S3 : P {<br>
&gt;     static func foo&lt;T&gt;(_ v: T) -&gt; (T, T, T) {<br>
&gt;         return (v, v, v)<br>
&gt;     }<br>
&gt; }<br>
&gt;<br>
&gt; (I&#39;m guessing but am not sure that I&#39;ve run into (yet) a(nother) situation which would require higher kinded types?)<br>
</div></div>&gt; ______________________________<wbr>_________________<br>
&gt; swift-users mailing list<br>
&gt; <a href="mailto:swift-users@swift.org">swift-users@swift.org</a><br>
&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-users" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-users</a><br>
<br>
</blockquote></div><br></div>