Optional

let nilString: String? = nil
let string   : String? = "string"
// swift/stdlib/public/core/Optional.swift
@frozen
public enum Optional<Wrapped> : ExpressibleByNilLiteral {
  case none
  case some(Wrapped)

  /// Creates an instance that stores the given value.
  @_transparent
  public init(_ some: Wrapped) { self = .some(some) }

  /// Creates an instance initialized with `nil`.
  ///
  /// Do not call this initializer directly. It is used by the compiler when you
  /// initialize an `Optional` instance with a `nil` literal. For example:
  ///
  ///     var i: Index? = nil
  ///
  /// In this example, the assignment to the `i` variable calls this
  /// initializer behind the scenes.
  @_transparent
  public init(nilLiteral: ()) {
    self = .none
  }
}

Functor、Applicative & Monad

import UIKit

let a: String? = nil// "a" // nil // "1"

// swift/stdlib/public/core/Optional.swift
//@frozen
//public enum Optional<Wrapped> : ExpressibleByNilLiteral {
//    case none
//    case some(Wrapped)
//
//    /// Creates an instance that stores the given value.
//    @_transparent
//    public init(_ some: Wrapped) { self = .some(some) }
//
//    /// Creates an instance initialized with `nil`.
//    ///
//    /// Do not call this initializer directly. It is used by the compiler when you
//    /// initialize an `Optional` instance with a `nil` literal. For example:
//    ///
//    ///     var i: Index? = nil
//    ///
//    /// In this example, the assignment to the `i` variable calls this
//    /// initializer behind the scenes.
//    @_transparent
//    public init(nilLiteral: ()) {
//        self = .none
//    }
//}

// b: Int?
// 1. a == "1" => b == 1?
// 2. a == nil => b == nil
// 3. a == "a" => b == nil
// 对于内部的闭包:(Wrapped) -> U? => value -> [ value ]
// 虽然闭包将 value 包装为 [ value ],但 .some 情况直接返回了闭包的返回类型
let b = a.flatMap { str -> Int? in
    return Int(str)
}

//@inlinable
//public func flatMap<U>(
//    _ transform: (Wrapped) throws -> U?
//    ) rethrows -> U? {
//    switch self {
//               let y: 对 self 解包得到 y
//    case .some(let y):
//                   transform(y): 对 y 做变换
//        return try transform(y)
//    case .none:
//               .none: 与无法解包的可能拼装
//        return .none
//    }
//}

// c: Int?
// 1. a == "1" => c == 5
// 2. a == nil => c == 5
// 3. a == "a" => c == 5
// 对于内部的闭包:(Wrapped) -> U => value -> value
let c = a.map { str -> Int in
    return 5
}

// d: Int??
// 1. a == "1" => d == 1??
// 2. a == nil => d == nil?
// 3. a == "a" => d == nil?
// 对于内部的闭包:(Wrapped) -> U => value -> value
// 不同的是,因为我们把 U 定义为了 Int?,所以返回的 value 也算是 [ value ]
// 而 .some 情况又对结果进行了二次包装,因此返回了 [[ value ]]
let d = a.map { str -> Int? in
    return Int(str)
}

//@inlinable
//public func map<U>(
//    _ transform: (Wrapped) throws -> U
//    ) rethrows -> U? {
//    switch self {
//               let y: 对 self 解包得到 y
//    case .some(let y):
//                   transform(y): 对 y 做变换
//               .some: 对变换结果包装
//        return .some(try transform(y))
//    case .none:
//               .none: 与无法解包的可能拼装
//        return .none
//    }
//}
//}

// Applicative
extension Optional {
    func apply<U>(f: ((Wrapped) -> U)?) -> U? {
        switch f {
        case .some(let someF):
            return self.map(someF)
        default:
            return .none
        }
    }
}

extension Array {
    func apply<U>(fs: [(Element) -> U]) -> [U] {
        var result = [U]()
        for f in fs {
            for element in self.map(f) {
                result.append(element)
            }
        }
        return result
    }
}

  • flatMap:对自己解包,然后应用到一个闭包上,这个闭包:接受一个「未封装的值」,返回一个「封装后的值」。
  • map:对自己解包,然后应用到一个闭包上,这个闭包:接受一个「未封装的值」,返回一个「未封装的值」。
  • apply:对自己解包,然后对闭包解包,解包后的闭包:接受一个「未封装的值」,返回一个「未封装的值」

PromiseKit ReactiveCocoa Rx

await/async

Reference