Pebble Coding

プログラマーの作業メモ

enum Optional<Wrapped> の map, flatMapメソッド

swiftのソースでmapとflatMapというメソッドがよく出てくるのだが、このメソッド名からは想像できない動作をするのでメモしておく。 (メソッド名変えてくんないかな。。)

Optionalの定義を見ると次のようになっている。

public enum Optional<Wrapped> : ExpressibleByNilLiteral {
  case none
  case some(Wrapped)
  public init(_ some: Wrapped)
  public init(nilLiteral: ())

  // mapメソッドはオプショナルではない値を返すクロージャを引数に取る。
  // 戻り値はオプショナル。
  public func map<U>(_ transform: (Wrapped) throws -> U)
      rethrows -> U?

  // flatMapメソッドはオプショナルの値を返すクロージャを引数に取る。。
  // 戻り値はオプショナル。
  public func flatMap<U>(_ transform: (Wrapped) throws -> U?)
      rethrows -> U?
}

mapの例

let a: Int? = Int("3")
let b: Int? = a.map { $0 * $0 }
print(b)
// Prints "Optional(9)"

let c: Int? = nil
let d: Int? = c.map { $0 * $0 }
print(d)
// Prints "nil"

flatMapの例

let a: Int? = Int("3")
let b: Int? = a.flatMap { x -> Int? in
  let (result, overflowed) = Int.multiplyWithOverflow(x, x)
  return overflowed ? nil : result
}
print(b)
// Prints "Optional(9)"

mapもflatMapもどちらも同じような動作をするが、クロージャの戻り値がnilになる場合がある時はflatMapを使い、それ以外はmapを使うという使い分けになるだろうか。