A More Swifty Way to Check an Optional for a Nil Value

Optional.flatMap and your let do the exact same thing. Here's its implementation in the standard library, check it out yourself.

To explain why...

It looks like you’re confusing Sequence.map with Optional.map.
Despite the same name, there is no iteration happening inside Optional.map. So why are they called the same? Because they both represent the same monadic operation. Let me explain.

To break it down simply, map is an abstraction that transforms values inside a container. It takes a Container<Content> and returns Container<NewContent> when you give it a closure that turns Content into NewContent.

For example:

  • Optional<Wrapped> has func map<T>(transform: (Wrapped) -> T) -> Optional<T>
  • Result<Success, Failure> has func map<T>(transform: (Success) -> T) -> Result<T, Failure>
  • Array<Element> has func map<T>(transform: (Element) -> T) -> Array<T>
  • Publisher<Output, Failure> has func map<T>(transform: (Output) -> T) -> Publisher<T, Failure>

The same applies to flatMap, but it’s used when the closure returns a whole new container. Instead of nesting them as map would Optional<Optional<Wrapped>>, flatMap flattens them to just Optional<Wrapped>.

Again, this behavior applies to different types:

  • Optional<Wrapped> has func flatMap<T>(transform: (Wrapped) -> Optional<T>) -> Optional<T>
  • Result<Success, Failure> has func flatMap<T>(transform: (Success) -> Result<T, Failure>) -> Result<T, Failure>
  • Array<Element> has func flatMap<T>(transform: (Element) -> Array<T>) -> Array<T>
  • Publisher<Output, Failure> has func flatMap<T>(transform: (Output) -> Publisher<T, Failure>) -> Publisher<T, Failure>

Think of Optional as just another container type and the names map and flatMap will make much more sense.

Note: These function signatures are simplified for explanation purposes. In practice, they handle more advanced cases, like rethrowing errors, working with ~Copyable containers, or returning specialized types such as Publishers.FlatMap or LazyMapSequence.


Fun fact: optional chaining is just syntactic sugar over flatMap:

let message: String? = "Hello"
message?.min() // Character?
message.flatMap { $0.min() } // Character?
1 Like

Thanks for reply,

effectively I was not aware of the difference between Sequence and Optional flatMap as could be mean by my dumb assumption. :disappointed: