Kekka 0.8.1

Kekka 0.8.1

Vijaya P. Kandel 维护。



Kekka 0.8.1

Kekka

已实现功能

结果

  • 对可能失败的类型的抽象(上下文类型,即网络结果)
        enum MathError: Error {
        case cannotDivideByZero
      }
    
      func divide(item: Int, by: Int) -> Result<Double> {
          if by == 0 { return .failure(error: MathError.cannotDivideByZero) }
          return .success(value: Double(item / by))
      }
  • 提供 mapflatMap(即 bind
      /// map [Functor]
      divide(item: 12, by: 0).map { $0 * 2 }  // still .failure(.cannotDivideByZero)
      divide(item: 12, by: 6).map { $0 * 2 }  // .success(4)
    
      /// flatMap | bind [Monad]
      divide(item: 12, by: 6).flatMap { divide(item: Int($0), by: 2) }  // .success(1)

未来

  • 对异步任务和嵌套回调的抽象(即动画、网络、文件读取)

      final class Network {
    
          public enum NetworkError: Error {
              case unknown
          }
    
          /// This is a much better way of wrapping network calls. 
          public func get(from url: URL) -> Future<Result<Data>> {
              return Future { aCompletion in
                  let session = URLSession(configuration: .default)
                  let dataTask = session.dataTask(with: url) { (data, response, error) in
                      if let d = data, error == nil {
                          aCompletion?(.success(value: d))
                      } else if let e = error {
                          aCompletion?(.failure(error: e))
                      } else {
                          aCompletion?(.failure(error: NetworkError.unknown))
                      }
                  }
                  dataTask.resume()
              }
          }
    
      }
  • 提供 map(即 then)和 flatMap(即 bind

    /// This allows one to reason code in linear way without the threading involved. 
    let url = URL(string: "https://www.kandelvijaya.com")!
    Network().get(from: url).map { transformToModel($0) }   // produces Future<Result<[XModel]>>
                            .map { viewModels(from: $0) }   // produces Future<Result<[XViewModel]>>
                            .execute()
    
    /// This allows one to chain multiple future/async task into a linear way
    Network().get(from: url).map { extractUrls($0).first }   // gets first external url
                            .flatMap { Network().get(from: $0) }  // gets data from that url 
                            .map { transformToModel($0) }  // produces Future<Result<XViewModel>>
                            .execute()
  • Result 和 Future 可以无缝工作,实现既易于推理又优雅的代码。相同的技巧可以用于链式动画、IO 和副作用编程。

待实现

IO

  • 不纯计算的抽象(捕获副作用)

贡献策略

  • 不追求基本的证明,而是提供语法糖和花哨的扩展
  • 否则,请随意创建问题或拉取请求。