# Problem with extension using generic constraint

**URL:** <https://forums.swift.org/t/problem-with-extension-using-generic-constraint/20283>\
**Category:** Using Swift\
**Created:** [February 8, 2019, 3:11pm UTC](https://forums.swift.org/t/problem-with-extension-using-generic-constraint/20283 "2019-02-08T15:11:45Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![dirk68](https://avatars.discourse-cdn.com/v4/letter/d/ee7513/32.png) [@dirk68](https://forums.swift.org/u/dirk68)\
**Post date:** [February 8, 2019, 3:11pm UTC](https://forums.swift.org/t/problem-with-extension-using-generic-constraint/20283/1 "2019-02-08T15:11:45Z")

</div>

Hi,

I wanted to write an extension to „Optional where Wrapped == String“ which provides a calculated property named makeNilIfEmpty, which should return nil if the optional is nil or the string is empty and the optional string otherwise.  
Please let's not discuss if this is useful.

This seems to work, see code below. Than I thought: „isEmpty“ is a property on Collection, why not define the extension on „Optional where Wrapped == Collection“ and extend the functionality to all Collections.

With String this works, with Collection I get the error: „ 'String?' is not convertible to 'Optional'“.

How would I correctly specify the return type of makeNilIfEmpty?  
Or am I trying to do something that is not possible?

```
//extension Optional where Wrapped == Collection {
extension Optional where Wrapped == String {
var makeNilIfEmpty:Optional<Wrapped>{
    if self == nil {
        return nil
    }
    if self!.isEmpty {
        return nil
    }
    return self
}
}

let a:String? = nil
let b:String? = ""
let c:String? = "Test"

print([a,b,c].map{$0.makeNilIfEmpty})

```

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [February 8, 2019, 3:17pm UTC](https://forums.swift.org/t/problem-with-extension-using-generic-constraint/20283/2 "2019-02-08T15:17:39Z")

</div>

You used same-type-requirement in form of `Wrapped == Collection` where actually you needed `Wrapped: Collection` constraint.

```swift
extension Optional where Wrapped: Collection {
  var makeNilIfEmpty: Wrapped? {
    return flatMap { $0.isEmpty ? .none : $0 }
  }
}

```

---

<div class="post-metadata">

**Author:** ![dirk68](https://avatars.discourse-cdn.com/v4/letter/d/ee7513/32.png) [@dirk68](https://forums.swift.org/u/dirk68)\
**Post date:** [February 8, 2019, 3:40pm UTC](https://forums.swift.org/t/problem-with-extension-using-generic-constraint/20283/3 "2019-02-08T15:40:29Z")

</div>

Thanks. That makes sense.

And thanks for the compact code. But would it perform as well?

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [February 8, 2019, 3:42pm UTC](https://forums.swift.org/t/problem-with-extension-using-generic-constraint/20283/4 "2019-02-08T15:42:41Z")

</div>

I'm not that much of a benchmark expert myself, but I would expect this to be the same as your example.

> <https://github.com/apple/swift/blob/main/stdlib/public/core/Optional.swift#L191-L201>

---

<div class="post-metadata">

**Author:** ![dirk68](https://avatars.discourse-cdn.com/v4/letter/d/ee7513/32.png) [@dirk68](https://forums.swift.org/u/dirk68)\
**Post date:** [February 8, 2019, 3:53pm UTC](https://forums.swift.org/t/problem-with-extension-using-generic-constraint/20283/5 "2019-02-08T15:53:23Z")

</div>

Thanks again. I would agree.

Any idea for a swiftier name than **makeNilIfEmpty**?

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [February 8, 2019, 3:57pm UTC](https://forums.swift.org/t/problem-with-extension-using-generic-constraint/20283/6 "2019-02-08T15:57:01Z")

</div>

Well I personally would go into a different direction.

```swift
extension Collection {
  var nonEmpty: NonEmpty<Self>? {
    if isEmpty { return .none }
    return NonEmpty(self[startIndex], self[index(after: startIndex)...])
  }
}

```

> **[GitHub - pointfreeco/swift-nonempty: 🎁 A compile-time guarantee that a...](https://github.com/pointfreeco/swift-nonempty)**
>
> 🎁 A compile-time guarantee that a collection contains a value. - GitHub - pointfreeco/swift-nonempty: 🎁 A compile-time guarantee that a collection contains a value.

* * *

But to answer your question maybe `noneIfEmpty` would read well as a variable.

---

<div class="post-metadata">

**Author:** ![dirk68](https://avatars.discourse-cdn.com/v4/letter/d/ee7513/32.png) [@dirk68](https://forums.swift.org/u/dirk68)\
**Post date:** [February 8, 2019, 4:28pm UTC](https://forums.swift.org/t/problem-with-extension-using-generic-constraint/20283/7 "2019-02-08T16:28:51Z")

</div>

> [@DevAndArtist](#):
>
> Well I personally would go into a different direction...

That would be a better choice for some problems but I need to Decode JSON data into my model and I want to have nil values instead of the empy strings the server provides.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [February 8, 2019, 4:31pm UTC](https://forums.swift.org/t/problem-with-extension-using-generic-constraint/20283/8 "2019-02-08T16:31:58Z")

</div>

Well in theory this exactly what you will get, and as a bonus you'll get more guarantee that whenever you unwrap the type it's a collection that is guaranteed to be non-empty. Again this is my personal preference, you can go with `noneIfEmpty` solution if it's the simplest and enough for your needs. 🙂

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [February 8, 2019, 6:27pm UTC](https://forums.swift.org/t/problem-with-extension-using-generic-constraint/20283/9 "2019-02-08T18:27:34Z")

</div>

In case you have other scenarios where you might need to fallback to `.none` you could create a helper extension on `Optional` and slightly modify the implementation of `noneIfEmpty`.

```swift
extension Optional {
  func filter(
    _ isIncluded: (Wrapped) throws -> Bool
  ) rethrows -> Optional {
    switch self {
    case .some(let value):
      return try isIncluded(value) ? value : .none
    case .none:
      return .none
    }
  }
}

extension Optional where Wrapped: Collection {
  var noneIfEmpty: Wrapped? {
    return filter { $0.isEmpty == false }
  }
}

```

Alternatively you can drop `noneIfEmpty` and just use `filter` instead.
