What does [[Element].Element] mean in Swift's == operator overload?











up vote
4
down vote

favorite












Swift's Array type implements Equatable protocol in a way that == and != operators are overloaded:



extension Array : Equatable where Element : Equatable {

/// - Parameters:
/// - lhs: An array to compare.
/// - rhs: Another array to compare.
public static func == (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool

public static func != (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool
}


I've got three questions:




  1. What is [[Element].Element]?

  2. How to read that?

  3. Why I cannot use that construct in my Swift code?


So far my reasoning is:





  1. [Element] is a type definition, i.e. an array of types denoted by
    Element (Element is a placeholder type name).

  2. Based on 1, next I reckon outermost brackets denote another array, BUT...

  3. I can't figure out what [Element].Element means as .Element is puzzling for me.










share|improve this question




















  • 2




    That code doesn't even compile, where did you get that from? That's not from the official Swift source code of Array.
    – Dávid Pásztor
    Nov 8 at 11:53










  • @DávidPásztor: Actually, if you select the “==” in if array1 == array2 and choose "Navigate -> Jump to Definition” in Xcode (10.1) then you'll see exactly the above definition. – Probably an artefact of the generated interface.
    – Martin R
    Nov 8 at 12:12












  • @DávidPásztor Jump to definition on Array type in Xcode and then look up Equatable. That's a real bummer that Xcode could not show the interface generated properly from the code you've linked to.
    – matm
    Nov 8 at 12:24

















up vote
4
down vote

favorite












Swift's Array type implements Equatable protocol in a way that == and != operators are overloaded:



extension Array : Equatable where Element : Equatable {

/// - Parameters:
/// - lhs: An array to compare.
/// - rhs: Another array to compare.
public static func == (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool

public static func != (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool
}


I've got three questions:




  1. What is [[Element].Element]?

  2. How to read that?

  3. Why I cannot use that construct in my Swift code?


So far my reasoning is:





  1. [Element] is a type definition, i.e. an array of types denoted by
    Element (Element is a placeholder type name).

  2. Based on 1, next I reckon outermost brackets denote another array, BUT...

  3. I can't figure out what [Element].Element means as .Element is puzzling for me.










share|improve this question




















  • 2




    That code doesn't even compile, where did you get that from? That's not from the official Swift source code of Array.
    – Dávid Pásztor
    Nov 8 at 11:53










  • @DávidPásztor: Actually, if you select the “==” in if array1 == array2 and choose "Navigate -> Jump to Definition” in Xcode (10.1) then you'll see exactly the above definition. – Probably an artefact of the generated interface.
    – Martin R
    Nov 8 at 12:12












  • @DávidPásztor Jump to definition on Array type in Xcode and then look up Equatable. That's a real bummer that Xcode could not show the interface generated properly from the code you've linked to.
    – matm
    Nov 8 at 12:24















up vote
4
down vote

favorite









up vote
4
down vote

favorite











Swift's Array type implements Equatable protocol in a way that == and != operators are overloaded:



extension Array : Equatable where Element : Equatable {

/// - Parameters:
/// - lhs: An array to compare.
/// - rhs: Another array to compare.
public static func == (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool

public static func != (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool
}


I've got three questions:




  1. What is [[Element].Element]?

  2. How to read that?

  3. Why I cannot use that construct in my Swift code?


So far my reasoning is:





  1. [Element] is a type definition, i.e. an array of types denoted by
    Element (Element is a placeholder type name).

  2. Based on 1, next I reckon outermost brackets denote another array, BUT...

  3. I can't figure out what [Element].Element means as .Element is puzzling for me.










share|improve this question















Swift's Array type implements Equatable protocol in a way that == and != operators are overloaded:



extension Array : Equatable where Element : Equatable {

/// - Parameters:
/// - lhs: An array to compare.
/// - rhs: Another array to compare.
public static func == (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool

public static func != (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool
}


I've got three questions:




  1. What is [[Element].Element]?

  2. How to read that?

  3. Why I cannot use that construct in my Swift code?


So far my reasoning is:





  1. [Element] is a type definition, i.e. an array of types denoted by
    Element (Element is a placeholder type name).

  2. Based on 1, next I reckon outermost brackets denote another array, BUT...

  3. I can't figure out what [Element].Element means as .Element is puzzling for me.







swift






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 8 at 12:30

























asked Nov 8 at 11:40









matm

6,11942949




6,11942949








  • 2




    That code doesn't even compile, where did you get that from? That's not from the official Swift source code of Array.
    – Dávid Pásztor
    Nov 8 at 11:53










  • @DávidPásztor: Actually, if you select the “==” in if array1 == array2 and choose "Navigate -> Jump to Definition” in Xcode (10.1) then you'll see exactly the above definition. – Probably an artefact of the generated interface.
    – Martin R
    Nov 8 at 12:12












  • @DávidPásztor Jump to definition on Array type in Xcode and then look up Equatable. That's a real bummer that Xcode could not show the interface generated properly from the code you've linked to.
    – matm
    Nov 8 at 12:24
















  • 2




    That code doesn't even compile, where did you get that from? That's not from the official Swift source code of Array.
    – Dávid Pásztor
    Nov 8 at 11:53










  • @DávidPásztor: Actually, if you select the “==” in if array1 == array2 and choose "Navigate -> Jump to Definition” in Xcode (10.1) then you'll see exactly the above definition. – Probably an artefact of the generated interface.
    – Martin R
    Nov 8 at 12:12












  • @DávidPásztor Jump to definition on Array type in Xcode and then look up Equatable. That's a real bummer that Xcode could not show the interface generated properly from the code you've linked to.
    – matm
    Nov 8 at 12:24










2




2




That code doesn't even compile, where did you get that from? That's not from the official Swift source code of Array.
– Dávid Pásztor
Nov 8 at 11:53




That code doesn't even compile, where did you get that from? That's not from the official Swift source code of Array.
– Dávid Pásztor
Nov 8 at 11:53












@DávidPásztor: Actually, if you select the “==” in if array1 == array2 and choose "Navigate -> Jump to Definition” in Xcode (10.1) then you'll see exactly the above definition. – Probably an artefact of the generated interface.
– Martin R
Nov 8 at 12:12






@DávidPásztor: Actually, if you select the “==” in if array1 == array2 and choose "Navigate -> Jump to Definition” in Xcode (10.1) then you'll see exactly the above definition. – Probably an artefact of the generated interface.
– Martin R
Nov 8 at 12:12














@DávidPásztor Jump to definition on Array type in Xcode and then look up Equatable. That's a real bummer that Xcode could not show the interface generated properly from the code you've linked to.
– matm
Nov 8 at 12:24






@DávidPásztor Jump to definition on Array type in Xcode and then look up Equatable. That's a real bummer that Xcode could not show the interface generated properly from the code you've linked to.
– matm
Nov 8 at 12:24














1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










Generally, TypeA.TypeB can denote a nested type or type alias TypeB
inside TypeA, or an associated type TypeB of a protocol TypeA.



Array conforms to Sequence, and that has an associatedtype Element
for the type of the elements returned from its iterator. For arrays
that is equal to the array's element type. So for any type T:



Array<T>.Element == T


and consequently,



[Array<T>.Element] == [T]


Example:



print(type(of: [Array<Int>.Element].self))
// Array<Int>.Type


However, using the bracket notation for the inner array is not accepted
by the compiler:



print(type(of: [[Int].Element].self))
// Expected member name or constructor call after type name


Now back to your question: The actual definition of that == operator is



extension Array : Equatable where Element : Equatable {
public static func ==(lhs: Array<Element>, rhs: Array<Element>) -> Bool {
// ...
}
}


The “generated interface” is, as you noticed:



extension Array : Equatable where Element : Equatable {
public static func == (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool
}


So apparently, the “interface generator” interprets the Element
in lhs: Array<Element> not as the placeholder type, but as the associated
Element type of the Sequence protocol, i.e. the types of the operands
are



Array<Array<Element>.Element>


which – as shown above – is just [Element]. But then the interface
is emitted using the bracket notation



[[Element].Element]


which should be the same, but is not accepted by the compiler.






share|improve this answer























  • thank you for a very insightful answer. Following simple logic, since Array<T>.Element == T is a tautology, so when array literal is applied, the end result is equivalent to Array<Element>. I've accepted the answer. Many thanks for your detailed answer.
    – matm
    Nov 9 at 9:12











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53207017%2fwhat-does-element-element-mean-in-swifts-operator-overload%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










Generally, TypeA.TypeB can denote a nested type or type alias TypeB
inside TypeA, or an associated type TypeB of a protocol TypeA.



Array conforms to Sequence, and that has an associatedtype Element
for the type of the elements returned from its iterator. For arrays
that is equal to the array's element type. So for any type T:



Array<T>.Element == T


and consequently,



[Array<T>.Element] == [T]


Example:



print(type(of: [Array<Int>.Element].self))
// Array<Int>.Type


However, using the bracket notation for the inner array is not accepted
by the compiler:



print(type(of: [[Int].Element].self))
// Expected member name or constructor call after type name


Now back to your question: The actual definition of that == operator is



extension Array : Equatable where Element : Equatable {
public static func ==(lhs: Array<Element>, rhs: Array<Element>) -> Bool {
// ...
}
}


The “generated interface” is, as you noticed:



extension Array : Equatable where Element : Equatable {
public static func == (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool
}


So apparently, the “interface generator” interprets the Element
in lhs: Array<Element> not as the placeholder type, but as the associated
Element type of the Sequence protocol, i.e. the types of the operands
are



Array<Array<Element>.Element>


which – as shown above – is just [Element]. But then the interface
is emitted using the bracket notation



[[Element].Element]


which should be the same, but is not accepted by the compiler.






share|improve this answer























  • thank you for a very insightful answer. Following simple logic, since Array<T>.Element == T is a tautology, so when array literal is applied, the end result is equivalent to Array<Element>. I've accepted the answer. Many thanks for your detailed answer.
    – matm
    Nov 9 at 9:12















up vote
2
down vote



accepted










Generally, TypeA.TypeB can denote a nested type or type alias TypeB
inside TypeA, or an associated type TypeB of a protocol TypeA.



Array conforms to Sequence, and that has an associatedtype Element
for the type of the elements returned from its iterator. For arrays
that is equal to the array's element type. So for any type T:



Array<T>.Element == T


and consequently,



[Array<T>.Element] == [T]


Example:



print(type(of: [Array<Int>.Element].self))
// Array<Int>.Type


However, using the bracket notation for the inner array is not accepted
by the compiler:



print(type(of: [[Int].Element].self))
// Expected member name or constructor call after type name


Now back to your question: The actual definition of that == operator is



extension Array : Equatable where Element : Equatable {
public static func ==(lhs: Array<Element>, rhs: Array<Element>) -> Bool {
// ...
}
}


The “generated interface” is, as you noticed:



extension Array : Equatable where Element : Equatable {
public static func == (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool
}


So apparently, the “interface generator” interprets the Element
in lhs: Array<Element> not as the placeholder type, but as the associated
Element type of the Sequence protocol, i.e. the types of the operands
are



Array<Array<Element>.Element>


which – as shown above – is just [Element]. But then the interface
is emitted using the bracket notation



[[Element].Element]


which should be the same, but is not accepted by the compiler.






share|improve this answer























  • thank you for a very insightful answer. Following simple logic, since Array<T>.Element == T is a tautology, so when array literal is applied, the end result is equivalent to Array<Element>. I've accepted the answer. Many thanks for your detailed answer.
    – matm
    Nov 9 at 9:12













up vote
2
down vote



accepted







up vote
2
down vote



accepted






Generally, TypeA.TypeB can denote a nested type or type alias TypeB
inside TypeA, or an associated type TypeB of a protocol TypeA.



Array conforms to Sequence, and that has an associatedtype Element
for the type of the elements returned from its iterator. For arrays
that is equal to the array's element type. So for any type T:



Array<T>.Element == T


and consequently,



[Array<T>.Element] == [T]


Example:



print(type(of: [Array<Int>.Element].self))
// Array<Int>.Type


However, using the bracket notation for the inner array is not accepted
by the compiler:



print(type(of: [[Int].Element].self))
// Expected member name or constructor call after type name


Now back to your question: The actual definition of that == operator is



extension Array : Equatable where Element : Equatable {
public static func ==(lhs: Array<Element>, rhs: Array<Element>) -> Bool {
// ...
}
}


The “generated interface” is, as you noticed:



extension Array : Equatable where Element : Equatable {
public static func == (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool
}


So apparently, the “interface generator” interprets the Element
in lhs: Array<Element> not as the placeholder type, but as the associated
Element type of the Sequence protocol, i.e. the types of the operands
are



Array<Array<Element>.Element>


which – as shown above – is just [Element]. But then the interface
is emitted using the bracket notation



[[Element].Element]


which should be the same, but is not accepted by the compiler.






share|improve this answer














Generally, TypeA.TypeB can denote a nested type or type alias TypeB
inside TypeA, or an associated type TypeB of a protocol TypeA.



Array conforms to Sequence, and that has an associatedtype Element
for the type of the elements returned from its iterator. For arrays
that is equal to the array's element type. So for any type T:



Array<T>.Element == T


and consequently,



[Array<T>.Element] == [T]


Example:



print(type(of: [Array<Int>.Element].self))
// Array<Int>.Type


However, using the bracket notation for the inner array is not accepted
by the compiler:



print(type(of: [[Int].Element].self))
// Expected member name or constructor call after type name


Now back to your question: The actual definition of that == operator is



extension Array : Equatable where Element : Equatable {
public static func ==(lhs: Array<Element>, rhs: Array<Element>) -> Bool {
// ...
}
}


The “generated interface” is, as you noticed:



extension Array : Equatable where Element : Equatable {
public static func == (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool
}


So apparently, the “interface generator” interprets the Element
in lhs: Array<Element> not as the placeholder type, but as the associated
Element type of the Sequence protocol, i.e. the types of the operands
are



Array<Array<Element>.Element>


which – as shown above – is just [Element]. But then the interface
is emitted using the bracket notation



[[Element].Element]


which should be the same, but is not accepted by the compiler.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 8 at 19:28

























answered Nov 8 at 12:18









Martin R

387k54838947




387k54838947












  • thank you for a very insightful answer. Following simple logic, since Array<T>.Element == T is a tautology, so when array literal is applied, the end result is equivalent to Array<Element>. I've accepted the answer. Many thanks for your detailed answer.
    – matm
    Nov 9 at 9:12


















  • thank you for a very insightful answer. Following simple logic, since Array<T>.Element == T is a tautology, so when array literal is applied, the end result is equivalent to Array<Element>. I've accepted the answer. Many thanks for your detailed answer.
    – matm
    Nov 9 at 9:12
















thank you for a very insightful answer. Following simple logic, since Array<T>.Element == T is a tautology, so when array literal is applied, the end result is equivalent to Array<Element>. I've accepted the answer. Many thanks for your detailed answer.
– matm
Nov 9 at 9:12




thank you for a very insightful answer. Following simple logic, since Array<T>.Element == T is a tautology, so when array literal is applied, the end result is equivalent to Array<Element>. I've accepted the answer. Many thanks for your detailed answer.
– matm
Nov 9 at 9:12


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53207017%2fwhat-does-element-element-mean-in-swifts-operator-overload%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Post-Redirect-Get with Spring WebFlux and Thymeleaf

Xamarin.form Move up view when keyboard appear

JBPM : POST request for execute process go wrong