swiftgenericskeypaths

What is the correct syntax of type parameter packs for generic types (like KeyPaths)


I'm trying to find out what is the correct syntax to define type parameters pack for KeyPath

// let's say we have
final class A {

    var field1: Int
    var field2: String
    var field3: Bool

    init(field1: Int, field2: String, field3: Bool) {
        self.field1 = field1
        self.field2 = field2
        self.field3 = field3
    }

}

// i need something like this (but this syntax is wrong)
func update<each T>(_ update: repeat (field: each WritableKeyPath<A, T>, new: each T)) {
    repeat self[keyPath: each update.field] = each update.new
}

// usage example
update((\.field2, "new-2"), (\.field1, 14))
update((\.field3, false))

Solution

  • Write each before every pack type/value. In this case, it is T and update.

    func update<A, each T>(subject: inout A, _ update: repeat (field: WritableKeyPath<A, each T>, new: each T)) {
        repeat subject[keyPath: (each update).field] = (each update).new
    }
    

    Note it's (each update).field, not each update.field because field is not a pack. each sort of has a rather low "precedence".

    I was also not sure what self is referring to, since update is a global function. I have therefore made it take an extra parameter subject.