项目作者: John-Connolly

项目描述 :
Infix operators for SwiftNIOs monadic futures
高级语言: Swift
项目地址: git://github.com/John-Connolly/terse.git
创建时间: 2018-02-21T02:10:24Z
项目社区:https://github.com/John-Connolly/terse

开源协议:MIT License

下载



SwiftQ





MIT License


Swift 4.1

Implementations

Monad

>>- (flatMap) (left associative)

  1. public func >>- <A, B>(a: EventLoopFuture<A>, f: @escaping (A) -> EventLoopFuture<B>) -> EventLoopFuture<B>

-<< (flatMap) (right associative)

  1. public func -<< <A, B>(f: @escaping (A) -> EventLoopFuture<B>, a: EventLoopFuture<A>) -> EventLoopFuture<B>

>=> Left-to-right Kleisli composition of monads (left associative)

  1. public func >=> <A, B, C>(f: @escaping (A) -> EventLoopFuture<B>, g: @escaping (B) -> EventLoopFuture<C>) -> (A) -> EventLoopFuture<C>

<=< Kleisli composition of monads (right associative)

  1. public func <=< <A, B, C>(f: @escaping (B) -> EventLoopFuture<C>, g: @escaping (A) -> EventLoopFuture<B>) -> (A) -> EventLoopFuture<C>

Functor

<^> (map) (left associative)

  1. public func <^> <A, B>(a: EventLoopFuture<A>, f: @escaping (A) -> B) -> EventLoopFuture<B>

Applicative

<*> Applicative

  1. public func <*> <A, B>(f: EventLoopFuture<((A) -> B)>, a: EventLoopFuture<A>) -> EventLoopFuture<B>

Usage

  1. func get(with client: RedisClient, for data: RedisData) -> Future<RedisData> {
  2. return client.command("GET", [data])
  3. }
  4. private func terse(_ req: Request) throws -> Future<RedisResponse> {
  5. let client = try req.make(RedisClient.self)
  6. return get(with: client, for: "KEY")
  7. >>- curry(get)(client)
  8. >>- curry(get)(client)
  9. >>- curry(get)(client)
  10. <^> RedisResponse.init
  11. }

vs

  1. private func nested(_ req: Request) throws -> Future<RedisResponse> {
  2. let client = try req.make(RedisClient.self)
  3. return client.command("GET", ["key"]).flatMap(to: RedisResponse.self) { data in
  4. return client.command("GET", [data]).flatMap(to: RedisResponse.self) { data in
  5. return client.command("GET", [data]).map(to: RedisResponse.self) { data in
  6. return RedisResponse(data)
  7. }
  8. }
  9. }
  10. }

Kleisli composition of monads

>=> is a monadic version of function composition.

  1. func query(with: String) -> EventLoopFuture<Int> {
  2. return EventLoopFuture(2)
  3. }
  4. func updateCache(with id: Int) -> EventLoopFuture<String> {
  5. return EventLoopFuture("Success")
  6. }
  7. let queryAndUpdate = query >=> updateCache

Applicative

Applies a future function to a future value

Curry

Currying is the technique of translating the evaluation of a function that takes multiple arguments into evaluating a sequence of functions, each with a single argument.

  1. let renderer: (String, Encodable) -> Future<View> = try req.make(LeafRenderer.self).render
  2. curry(renderer) //(String) -> (Encodable) -> Future<View>
  3. overview >>- curry(renderer)("overview")

This is useful for using the operators with non unary functions.

SwiftPM

  1. .package(url: "https://github.com/John-Connolly/terse.git", from: "1.0.0")