title: Swift: Extension on [<SomeType<T>?] to produce [<T>?] possible?
body: <p><strong>In Swift, I have a custom struct with this basic premise:</strong></p>
  
  <p>A wrapper struct that can contain any type that conforms to <code>BinaryInteger</code> such as Int, UInt8, Int16, etc.</p>
  
  <pre><code>protocol SomeTypeProtocol {
      associatedtype NumberType
  
      var value: NumberType { get set }
  }
  
  struct SomeType&lt;T: BinaryInteger&gt;: SomeTypeProtocol {
      typealias NumberType = T
  
      var value: NumberType
  }
  </code></pre>
  
  <p>And an extension on Collection:</p>
  
  <pre><code>extension Collection where Element: SomeTypeProtocol {
      var values: [Element.NumberType] {
          return self.map { $0.value }
      }
  }
  </code></pre>
  
  <p>For example, this works nicely:</p>
  
  <pre><code>let arr = [SomeType(value: 123), SomeType(value: 456)]
  
  // this produces [123, 456] of type [Int] since literals are Int by default
  arr.values
  </code></pre>
  
  <p><strong>What I would like to do is the exact same thing, but for <code>SomeType&lt;T&gt;?</code></strong></p>
  
  <pre><code>let arr: [SomeType&lt;Int&gt;?] = [SomeType(value: 123), SomeType(value: 456)]
  
  // this doesn't work, obviously
  arr.values
  
  // but what I want is this:
  arr.values // to produce [Optional(123), Optional(456)]
  </code></pre>
  
  <p>I've tried numerous attempts to solve this and a fair amount of research, but I'm hoping any of the sage Swift veterans might shed some light on this.</p>
  
  <p>This is what I envision it might look like, but this doesn't work:</p>
  
  <pre><code>extension Collection where Element == Optional&lt;SomeType&lt;T&gt;&gt; {
      var values: [T?] {
          return self.map { $0?.value }
      }
  }
  </code></pre>
  
  <p><strong>This is a clumsy way of achieving the goal without using generics, and it works:</strong></p>
  
  <pre><code>extension Collection where Element == Optional&lt;SomeType&lt;Int&gt;&gt; {
      var values: [Int?] {
          return self.map { $0?.value }
      }
  }
  
  let arr: [SomeType&lt;Int&gt;?] = [SomeType(value: 123), SomeType(value: 456)]
  arr.values // [Optional(123), Optional(456)]
  </code></pre>
  
  <p>But it requires manually writing extensions for every known type conforming to BinaryInteger, and will not automatically include possible future types adopting BinaryInteger without manually updating the code.</p>
  
  <pre><code>// "..." would contain the var values code from above, copy-and-pasted
  extension Collection where Element == Optional&lt;SomeType&lt;Int&gt;&gt; { ... }
  extension Collection where Element == Optional&lt;SomeType&lt;Int8&gt;&gt; { ... }
  extension Collection where Element == Optional&lt;SomeType&lt;UInt8&gt;&gt; { ... }
  extension Collection where Element == Optional&lt;SomeType&lt;Int16&gt;&gt; { ... }
  extension Collection where Element == Optional&lt;SomeType&lt;UInt16&gt;&gt; { ... }
  extension Collection where Element == Optional&lt;SomeType&lt;Int32&gt;&gt; { ... }
  extension Collection where Element == Optional&lt;SomeType&lt;UInt32&gt;&gt; { ... }
  extension Collection where Element == Optional&lt;SomeType&lt;Int64&gt;&gt; { ... }
  extension Collection where Element == Optional&lt;SomeType&lt;UInt64&gt;&gt; { ... }
  </code></pre>
  
  <h1>EDIT 2018-Jun-23:</h1>
  
  <h2>Solution #1 - Fully Generic but Must be Func, Not Computed Property</h2>
  
  <p>Expanded on <a href="https://stackoverflow.com/a/51001112/2805570">Ole's reply</a>:</p>
  
  <p>Pros: If <code>values()</code> becomes a <code>func</code> and not a computed property, this is an elegant solution.</p>
  
  <p>Cons: No known way to implement this approach as computed properties, and Swift's Quick Help popup shows [T] and [T?] when inspecting <code>values()</code> in your code. ie: it just says <code>func values&lt;T&gt;() -&gt; [T] where T : BinaryInteger</code> which isn't very informative or Swifty. However it still remains strongly typed of course.</p>
  
  <pre><code>extension Collection {
      func values&lt;T&gt;() -&gt; [T] where Element == SomeType&lt;T&gt; {
          return map { $0.value }
      }
  
      func values&lt;T&gt;() -&gt; [T?] where Element == SomeType&lt;T&gt;? {
          return map { $0?.value }
      }
  }
  </code></pre>
  
  <h2>Solution #2 - Optional Protocol Workaround</h2>
  
  <p>Expanded on <a href="https://stackoverflow.com/a/50999846/2805570">Martin's reply</a>:</p>
  
  <p>Pros: Allows use of computed properties (cleaner for the end-user to access since it doesn't require func parens) and shows inferred type in Xcode's Quick Help popup.</p>
  
  <p>Cons: Not as elegant from an internal code standpoint, as it requires a workaround. But not necessarily a drawback.</p>
  
  <pre><code>// Define OptionalType
  
  protocol OptionalType {
      associatedtype Wrapped
      var asOptional: Wrapped? { get }
  }
  
  extension Optional: OptionalType {
      var asOptional: Wrapped? {
          return self
      }
  }
  
  // Extend Collection
  
  extension Collection where Element: SomeTypeProtocol {
      var values: [Element.NumberType] {
          return self.map { $0.value }
      }
  }
  
  extension Collection where Element: OptionalType, Element.Wrapped: SomeTypeProtocol {
      var values: [Element.Wrapped.NumberType?] {
          return self.map { $0.asOptional?.value }
      }
  }
  </code></pre>