Referring to operator of generic type

I have a structure that takes in comparator function. I want to default this to Comparable's operator < if Element is also Comparable:

struct Structure<Element> {
    let isLessThan: (Element, Element) -> Bool

    init(isLessThan: @escaping (Element, Element) -> Bool) {
        self.isLessThan = isLessThan
    }

    // I want to ultimately have this
    init() where Element: Comparable {
        isLessThan = <
    }
}

Right now generic type's method isn't implicitly generic, so I can make extension for the init function in the mean time.

The problem is referring to <. How can I do that?

This works for me:

struct Structure<Element> {

    let isLessThan: (Element, Element) -> Bool

    init(isLessThan: @escaping (Element, Element) -> Bool) {
        self.isLessThan = isLessThan
    }
}

extension Structure where Element: Comparable {

    init() {
        self.init(isLessThan: <)
    }
}

let x = Structure<Int>()

This works! Thank you.
Funny that assignment statement confuses the compiler.

FWIW, I have tried the Haskellish way of writing the operator and that seems to work, too:

self.isLessThan = (<)

But delegating the convenience initializer through the main one seems like a good idea anyway.

2 Likes

I think it’s by-design that you can only use operators as first-class values in limited contexts. And I think the two contexts are what you’ve encountered in this thread: inside arguments lists or when surrounded by parentheses.