How can I easily copy an immutable struct in swift, varying only some fields [Like kotlin dataclass copy method]?

Think, you can extend the struct with a copy(...) method taking nil values as default and replacing them with instance ones while using non-nil otherwise. E.g. something like this:

extension LogicalState {
    func copy(a: String? = nil, b: Bool? = nil, c: Int? = nil) -> LogicalState {
        return LogicalState(a: a ?? self.a, b: b ?? self.b, c: c ?? self.c)
    }
}

So you can use it to copy instance while varying the needed params:

let state = LogicalState(a: "A", b: false, c: 10)
let stateCopy1 = state.copy(c: 30)
let stateCopy2 = state.copy(a: "copy 2")

Another option would be to use a builder:

struct LogicalState {
  let a: String?
  let b: Bool
  let c: Int
}


extension LogicalState {
    func copy(build: (inout Builder) -> Void) -> LogicalState {
        var builder = Builder(state: self)
        build(&builder)
        
        return builder.toLogicalState()
    }
    
    struct Builder {
        var a: String?
        var b: Bool
        var c: Int
        
        fileprivate init(state: LogicalState) {
            self.a = state.a
            self.b = state.b
            self.c = state.c
        }
        
        fileprivate func toLogicalState() -> LogicalState {
            return LogicalState(a: a, b: b, c: c)
        }
    }
}

let state = LogicalState(a: "a", b: true, c: 0)
let nextState = state.copy { $0.a = nil }

Then we wouldn't have to deal with double optionals as mentioned by Orion Edwards.