SciTech.blog
SciTech.blog

Conditional conformance in Swift

24 Feb 2018, 03:50 • swift

Swift 4.1 brought an improvement to the language's type system called conditional conformance, which allows you to specify that a generic class conforms to a protocol based on the generic arguments' conformance to protocols. A simple example is presented.

Let's have two simple classes implementing a linked list:

class LinkedListElement<T> {
    let val:T
    var next:LinkedListElement<T>?
    init(val:T) { self.val = val }
}

class LinkedList<T> {
    var first:LinkedListElement<T>?
    var last:LinkedListElement<T>?
    func append(val:T) {
        let el = LinkedListElement(val: val)
        if let l = last {
            l.next = el
            last = el
        } else {
            first = el
            last = el
        }
    }
}

Note that the LinkedList class is generic, that is, it can store items of any type. It's clear that two lists are equatable if their elements is equatable, we just need to check that the lists have the same length and test all the elements for equality. In other words, if T conforms to Equatable, which is a built-in protocol, LinkedList can be made conform to this protocol too. Swift 4.1 allows us to do that:

extension LinkedList : Equatable where T:Equatable {
    static func ==(l1:LinkedList, l2:LinkedList) -> Bool {
        var el1 = l1.first
        var el2 = l2.first
        while el1 != nil && el2 != nil {
            if el1!.val != el2!.val { return false }
            el1 = el1!.next
            el2 = el2!.next
        }
        return el1 == nil && el2 == nil
    }
}

Note that this wasn't possible before (and it's impossible in many other programming languages) because there was no way of telling the compiler that the conformance is conditional. With this improvement, code can be more readable and more concise.

Comments

Name: