Main Nightly

Zippy 🤐

Zip 函数。

zipzipWith 在 Optional 类型上的应用

Zip 函数在 Swift 的序列中已经定义了。这是一个很好的扩展,可以将其应用在 Optional 类型上。

假设你有一些计算或值是 Optional 类型的。使用 if let 处理它们可能会很繁琐。使用 zip 你可以把容器翻转过来(查看这个 Haskell 中 zip 的文档 来了解类型的转换方式),然后在结果上进行 map 操作。

let userName: String? 
let userLast: String?
let userAge: Int? 

zip(userName, userLast, userAge)
    .map{ (name: String, last: String, age: Int) in 
        // Working with not optional values
     }

asyncZip

允许并发调用多个异步函数,以获取结果的元组。

let (name, age) = await asyncZip(
        await asyncGetUserName(), 
        await asyncGetUserAge()
    )

let user = User(name: name, age: age)

asyncZipWith

asyncZip 相同,但最后一个参数是一个函数,可以将这个元组转换成某种类型的实例。

struct User {
    let name: String
    let age: Int
}

let user: User = asyncZip(
        await asyncGetUserName(), 
        await asyncGetUserAge(),
        with: User.init
    )

在这个例子中,你可以直接写 User.init,因为编译器会自动匹配到正确的函数。但是你也可以使用闭包和尾随语法来做任何你需要的事情。

struct User {
    let name: String
    let age: Int
}

let user: User = asyncZip(
        await asyncGetUserName(), 
        await asyncGetUserAge()
    ) { (fetchedName: String, fetchedAge: Int) in
        User(name: fetchedName, age: fetchedAge)
    }

zipzipWithEither 类型上的应用

Either 是比 OptionalResult 更通用的类型,并且它也定义了 zip 函数(因为它有 map)。如果你想了解更多关于 Either 的信息,请查看这个仓库:EitherSwift Swift Package

let userName: Either<Int,String> = getUserNameOrErrorCode()
let userLastName: Either<Int,String> = getUserLastNameOrErrorCode()

zip(userName, userLastName)
    .map { (name: String, last: String) in 
        // When all are .right cases then you have the values here
     }

zipWith

很多时候,你运行代码是为了对返回值做一些事情。为了简化操作,你可以传递一个函数给 zipWith

func validateName    (_ s: String) -> Either<Int,String> { ... }
func validateLastName(_ s: String) -> Either<Int,String> { ... }

struct User { let name: String; let lastName: String }

// Given two Eithers when they both are right then returns User.
// Notice as this also returns an Either but luckely this type has a map.
let createUserWhenValid: Either<Int,String>,Either<Int,String>) -> Either<Int,User> = zip(with: User.init)   

createUserWhenValid(validateName, validateLastName) 
    .map { (user: User) in
        // Real instance of User type 😎
    }
    .mapLeft { (errorCodes: [Int]) in
        // error codes that were returned as left values
    }

Optional API

如果你想简化在 Swift 中使用 Optionals 的操作,请查看 OptionalAPI Swift Package。它有丰富的文档和测试来展示如何使用它。

🐇🕳 Rabbit Hole

这个项目是 🐇🕳 Rabbit Hole Packages Collection 的一部分