'Array' is not convertible to 'Array'
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I can create an iterator to create prefixes:
extension Array where Element == Int {
func prefixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.prefix(length))
}
}
}
for prefix in [1,10,5].prefixesInt() {
print(prefix) // Prints: [1] then [1, 10] then [1, 10, 5]
}
Now I want to achieve the same with other types by:
1) Encoding the types to Ints
2) Using the same prefix function
3) Decoding back to the original type
[I know there might be other ways to achieve this but I want to follow this line for various reasons and also wanting to understand more.]
So I need:
extension Array where Element: Equatable {
func encode() -> [Int] {
return map { self.firstIndex(of: $0)! }
}
}
print(["A", "B", "A", "C"].encode()) // Prints: [0, 1, 0, 3]
extension Array where Element == Int {
func decode<Output>(_ original: [Output]) -> [Output] {
return map { original[$0] }
}
}
print([2,3,0].decode(["P", "Q", "R", "S"])) // Prints: ["R", "S", "P"]
I can now do what I want with:
extension Array where Element: Equatable {
func prefixes() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encode().prefixesInt().lazy.map { $0.decode(self) }
}
}
for prefix in ["H","A","T"].prefixes() {
print(prefix)
}
I now want to go a step further by making the transform (in this case prefixes) into a parameter and my attempt is:
extension Array where Element: Equatable {
func encodeTransformDecode(transform: ([Int]) -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode()).lazy.map { $0.decode(self) }
}
}
which compiles fine but when I try:
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Element]>, [Element]> {
return encodeTransformDecode(transform: prefixesInt) //ERROR: 'Array<Element>' is not convertible to 'Array<Int>'
}
}
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
Then I get the error indicated
I'm stuck. Any help appreciated.
Whole code:
print("========== prefixesInt")
extension Array where Element == Int {
func prefixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.prefix(length))
}
}
}
for prefix in [1,10,5].prefixesInt() {
print(prefix) // Prints: [1] then [1, 10] then [1, 10, 5]
}
print("============ encode")
extension Array where Element: Equatable {
func encode() -> [Int] {
return map { self.firstIndex(of: $0)! }
}
}
print(["A", "B", "A", "C"].encode()) // Prints: [0, 1, 0, 3]
print("============ decode")
extension Array where Element == Int {
func decode<Output>(_ original: [Output]) -> [Output] {
return map { original[$0] }
}
}
print([2,3,0].decode(["P", "Q", "R", "S"])) // Prints: ["R", "S", "P"]
print("============ prefixes")
extension Array where Element: Equatable {
func prefixes() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encode().prefixesInt().lazy.map { $0.decode(self) }
}
}
for prefix in ["H","A","T"].prefixes() {
print(prefix)
}
extension Array where Element: Equatable {
func encodeTransformDecode(transform: ([Int]) -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode()).lazy.map { $0.decode(self) }
}
}
print("============ prefixes2")
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Element]>, [Element]> {
return encodeTransformDecode(transform: prefixesInt)
}
}
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
swift generics functional-programming lazy-sequences
|
show 4 more comments
I can create an iterator to create prefixes:
extension Array where Element == Int {
func prefixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.prefix(length))
}
}
}
for prefix in [1,10,5].prefixesInt() {
print(prefix) // Prints: [1] then [1, 10] then [1, 10, 5]
}
Now I want to achieve the same with other types by:
1) Encoding the types to Ints
2) Using the same prefix function
3) Decoding back to the original type
[I know there might be other ways to achieve this but I want to follow this line for various reasons and also wanting to understand more.]
So I need:
extension Array where Element: Equatable {
func encode() -> [Int] {
return map { self.firstIndex(of: $0)! }
}
}
print(["A", "B", "A", "C"].encode()) // Prints: [0, 1, 0, 3]
extension Array where Element == Int {
func decode<Output>(_ original: [Output]) -> [Output] {
return map { original[$0] }
}
}
print([2,3,0].decode(["P", "Q", "R", "S"])) // Prints: ["R", "S", "P"]
I can now do what I want with:
extension Array where Element: Equatable {
func prefixes() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encode().prefixesInt().lazy.map { $0.decode(self) }
}
}
for prefix in ["H","A","T"].prefixes() {
print(prefix)
}
I now want to go a step further by making the transform (in this case prefixes) into a parameter and my attempt is:
extension Array where Element: Equatable {
func encodeTransformDecode(transform: ([Int]) -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode()).lazy.map { $0.decode(self) }
}
}
which compiles fine but when I try:
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Element]>, [Element]> {
return encodeTransformDecode(transform: prefixesInt) //ERROR: 'Array<Element>' is not convertible to 'Array<Int>'
}
}
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
Then I get the error indicated
I'm stuck. Any help appreciated.
Whole code:
print("========== prefixesInt")
extension Array where Element == Int {
func prefixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.prefix(length))
}
}
}
for prefix in [1,10,5].prefixesInt() {
print(prefix) // Prints: [1] then [1, 10] then [1, 10, 5]
}
print("============ encode")
extension Array where Element: Equatable {
func encode() -> [Int] {
return map { self.firstIndex(of: $0)! }
}
}
print(["A", "B", "A", "C"].encode()) // Prints: [0, 1, 0, 3]
print("============ decode")
extension Array where Element == Int {
func decode<Output>(_ original: [Output]) -> [Output] {
return map { original[$0] }
}
}
print([2,3,0].decode(["P", "Q", "R", "S"])) // Prints: ["R", "S", "P"]
print("============ prefixes")
extension Array where Element: Equatable {
func prefixes() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encode().prefixesInt().lazy.map { $0.decode(self) }
}
}
for prefix in ["H","A","T"].prefixes() {
print(prefix)
}
extension Array where Element: Equatable {
func encodeTransformDecode(transform: ([Int]) -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode()).lazy.map { $0.decode(self) }
}
}
print("============ prefixes2")
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Element]>, [Element]> {
return encodeTransformDecode(transform: prefixesInt)
}
}
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
swift generics functional-programming lazy-sequences
2
prefixesInt
is only defined onArray where Element == Int
and not arrays in general
– ielyamani
Nov 16 '18 at 10:26
But encodeTransformDecode's signature is asking that transform has type: ([Int]) -> AnyIterator<[Int]> so not clear on the message?
– Adahus
Nov 16 '18 at 10:54
1
You can't callprefixesInt
from an array where the only constraint on element is to be equatable. Plus the signature ofprefixesInt
is not([Int]) -> AnyIterator<[Int]>
– ielyamani
Nov 16 '18 at 10:58
What version of Xcode/Swift are you using? Commenting out your error at the end and running produces output at expected plusSWIFT RUNTIME BUG: unable to demangle type of field '_transform'. mangled type name is 'q_7ElementSTQzc'
in Xcode 10.0/Swift 4.2 playground
– CRD
Nov 16 '18 at 11:08
1
I think one thing you are missing is that inencodeTransformDecode(transform: prefixesInt)
there is an implicitself
reference asprefixesInt
is an instance method – and in this case thatself
is not of type[Int]
. This gives you two problems, wrong type, and even if it was the right type you've implicitly bound theself
. If you define astatic
prefixesInt
method which takes an[Int]
and simply calls the instance version on its arg, pass that toencodeTransformDecode
, you'll get further. (I've got your code "working" in 10.0 but its spewing RUNTIME BUGs so won't post!)
– CRD
Nov 16 '18 at 11:49
|
show 4 more comments
I can create an iterator to create prefixes:
extension Array where Element == Int {
func prefixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.prefix(length))
}
}
}
for prefix in [1,10,5].prefixesInt() {
print(prefix) // Prints: [1] then [1, 10] then [1, 10, 5]
}
Now I want to achieve the same with other types by:
1) Encoding the types to Ints
2) Using the same prefix function
3) Decoding back to the original type
[I know there might be other ways to achieve this but I want to follow this line for various reasons and also wanting to understand more.]
So I need:
extension Array where Element: Equatable {
func encode() -> [Int] {
return map { self.firstIndex(of: $0)! }
}
}
print(["A", "B", "A", "C"].encode()) // Prints: [0, 1, 0, 3]
extension Array where Element == Int {
func decode<Output>(_ original: [Output]) -> [Output] {
return map { original[$0] }
}
}
print([2,3,0].decode(["P", "Q", "R", "S"])) // Prints: ["R", "S", "P"]
I can now do what I want with:
extension Array where Element: Equatable {
func prefixes() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encode().prefixesInt().lazy.map { $0.decode(self) }
}
}
for prefix in ["H","A","T"].prefixes() {
print(prefix)
}
I now want to go a step further by making the transform (in this case prefixes) into a parameter and my attempt is:
extension Array where Element: Equatable {
func encodeTransformDecode(transform: ([Int]) -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode()).lazy.map { $0.decode(self) }
}
}
which compiles fine but when I try:
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Element]>, [Element]> {
return encodeTransformDecode(transform: prefixesInt) //ERROR: 'Array<Element>' is not convertible to 'Array<Int>'
}
}
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
Then I get the error indicated
I'm stuck. Any help appreciated.
Whole code:
print("========== prefixesInt")
extension Array where Element == Int {
func prefixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.prefix(length))
}
}
}
for prefix in [1,10,5].prefixesInt() {
print(prefix) // Prints: [1] then [1, 10] then [1, 10, 5]
}
print("============ encode")
extension Array where Element: Equatable {
func encode() -> [Int] {
return map { self.firstIndex(of: $0)! }
}
}
print(["A", "B", "A", "C"].encode()) // Prints: [0, 1, 0, 3]
print("============ decode")
extension Array where Element == Int {
func decode<Output>(_ original: [Output]) -> [Output] {
return map { original[$0] }
}
}
print([2,3,0].decode(["P", "Q", "R", "S"])) // Prints: ["R", "S", "P"]
print("============ prefixes")
extension Array where Element: Equatable {
func prefixes() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encode().prefixesInt().lazy.map { $0.decode(self) }
}
}
for prefix in ["H","A","T"].prefixes() {
print(prefix)
}
extension Array where Element: Equatable {
func encodeTransformDecode(transform: ([Int]) -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode()).lazy.map { $0.decode(self) }
}
}
print("============ prefixes2")
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Element]>, [Element]> {
return encodeTransformDecode(transform: prefixesInt)
}
}
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
swift generics functional-programming lazy-sequences
I can create an iterator to create prefixes:
extension Array where Element == Int {
func prefixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.prefix(length))
}
}
}
for prefix in [1,10,5].prefixesInt() {
print(prefix) // Prints: [1] then [1, 10] then [1, 10, 5]
}
Now I want to achieve the same with other types by:
1) Encoding the types to Ints
2) Using the same prefix function
3) Decoding back to the original type
[I know there might be other ways to achieve this but I want to follow this line for various reasons and also wanting to understand more.]
So I need:
extension Array where Element: Equatable {
func encode() -> [Int] {
return map { self.firstIndex(of: $0)! }
}
}
print(["A", "B", "A", "C"].encode()) // Prints: [0, 1, 0, 3]
extension Array where Element == Int {
func decode<Output>(_ original: [Output]) -> [Output] {
return map { original[$0] }
}
}
print([2,3,0].decode(["P", "Q", "R", "S"])) // Prints: ["R", "S", "P"]
I can now do what I want with:
extension Array where Element: Equatable {
func prefixes() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encode().prefixesInt().lazy.map { $0.decode(self) }
}
}
for prefix in ["H","A","T"].prefixes() {
print(prefix)
}
I now want to go a step further by making the transform (in this case prefixes) into a parameter and my attempt is:
extension Array where Element: Equatable {
func encodeTransformDecode(transform: ([Int]) -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode()).lazy.map { $0.decode(self) }
}
}
which compiles fine but when I try:
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Element]>, [Element]> {
return encodeTransformDecode(transform: prefixesInt) //ERROR: 'Array<Element>' is not convertible to 'Array<Int>'
}
}
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
Then I get the error indicated
I'm stuck. Any help appreciated.
Whole code:
print("========== prefixesInt")
extension Array where Element == Int {
func prefixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.prefix(length))
}
}
}
for prefix in [1,10,5].prefixesInt() {
print(prefix) // Prints: [1] then [1, 10] then [1, 10, 5]
}
print("============ encode")
extension Array where Element: Equatable {
func encode() -> [Int] {
return map { self.firstIndex(of: $0)! }
}
}
print(["A", "B", "A", "C"].encode()) // Prints: [0, 1, 0, 3]
print("============ decode")
extension Array where Element == Int {
func decode<Output>(_ original: [Output]) -> [Output] {
return map { original[$0] }
}
}
print([2,3,0].decode(["P", "Q", "R", "S"])) // Prints: ["R", "S", "P"]
print("============ prefixes")
extension Array where Element: Equatable {
func prefixes() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encode().prefixesInt().lazy.map { $0.decode(self) }
}
}
for prefix in ["H","A","T"].prefixes() {
print(prefix)
}
extension Array where Element: Equatable {
func encodeTransformDecode(transform: ([Int]) -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode()).lazy.map { $0.decode(self) }
}
}
print("============ prefixes2")
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Element]>, [Element]> {
return encodeTransformDecode(transform: prefixesInt)
}
}
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
swift generics functional-programming lazy-sequences
swift generics functional-programming lazy-sequences
asked Nov 16 '18 at 9:56
AdahusAdahus
650718
650718
2
prefixesInt
is only defined onArray where Element == Int
and not arrays in general
– ielyamani
Nov 16 '18 at 10:26
But encodeTransformDecode's signature is asking that transform has type: ([Int]) -> AnyIterator<[Int]> so not clear on the message?
– Adahus
Nov 16 '18 at 10:54
1
You can't callprefixesInt
from an array where the only constraint on element is to be equatable. Plus the signature ofprefixesInt
is not([Int]) -> AnyIterator<[Int]>
– ielyamani
Nov 16 '18 at 10:58
What version of Xcode/Swift are you using? Commenting out your error at the end and running produces output at expected plusSWIFT RUNTIME BUG: unable to demangle type of field '_transform'. mangled type name is 'q_7ElementSTQzc'
in Xcode 10.0/Swift 4.2 playground
– CRD
Nov 16 '18 at 11:08
1
I think one thing you are missing is that inencodeTransformDecode(transform: prefixesInt)
there is an implicitself
reference asprefixesInt
is an instance method – and in this case thatself
is not of type[Int]
. This gives you two problems, wrong type, and even if it was the right type you've implicitly bound theself
. If you define astatic
prefixesInt
method which takes an[Int]
and simply calls the instance version on its arg, pass that toencodeTransformDecode
, you'll get further. (I've got your code "working" in 10.0 but its spewing RUNTIME BUGs so won't post!)
– CRD
Nov 16 '18 at 11:49
|
show 4 more comments
2
prefixesInt
is only defined onArray where Element == Int
and not arrays in general
– ielyamani
Nov 16 '18 at 10:26
But encodeTransformDecode's signature is asking that transform has type: ([Int]) -> AnyIterator<[Int]> so not clear on the message?
– Adahus
Nov 16 '18 at 10:54
1
You can't callprefixesInt
from an array where the only constraint on element is to be equatable. Plus the signature ofprefixesInt
is not([Int]) -> AnyIterator<[Int]>
– ielyamani
Nov 16 '18 at 10:58
What version of Xcode/Swift are you using? Commenting out your error at the end and running produces output at expected plusSWIFT RUNTIME BUG: unable to demangle type of field '_transform'. mangled type name is 'q_7ElementSTQzc'
in Xcode 10.0/Swift 4.2 playground
– CRD
Nov 16 '18 at 11:08
1
I think one thing you are missing is that inencodeTransformDecode(transform: prefixesInt)
there is an implicitself
reference asprefixesInt
is an instance method – and in this case thatself
is not of type[Int]
. This gives you two problems, wrong type, and even if it was the right type you've implicitly bound theself
. If you define astatic
prefixesInt
method which takes an[Int]
and simply calls the instance version on its arg, pass that toencodeTransformDecode
, you'll get further. (I've got your code "working" in 10.0 but its spewing RUNTIME BUGs so won't post!)
– CRD
Nov 16 '18 at 11:49
2
2
prefixesInt
is only defined on Array where Element == Int
and not arrays in general– ielyamani
Nov 16 '18 at 10:26
prefixesInt
is only defined on Array where Element == Int
and not arrays in general– ielyamani
Nov 16 '18 at 10:26
But encodeTransformDecode's signature is asking that transform has type: ([Int]) -> AnyIterator<[Int]> so not clear on the message?
– Adahus
Nov 16 '18 at 10:54
But encodeTransformDecode's signature is asking that transform has type: ([Int]) -> AnyIterator<[Int]> so not clear on the message?
– Adahus
Nov 16 '18 at 10:54
1
1
You can't call
prefixesInt
from an array where the only constraint on element is to be equatable. Plus the signature of prefixesInt
is not ([Int]) -> AnyIterator<[Int]>
– ielyamani
Nov 16 '18 at 10:58
You can't call
prefixesInt
from an array where the only constraint on element is to be equatable. Plus the signature of prefixesInt
is not ([Int]) -> AnyIterator<[Int]>
– ielyamani
Nov 16 '18 at 10:58
What version of Xcode/Swift are you using? Commenting out your error at the end and running produces output at expected plus
SWIFT RUNTIME BUG: unable to demangle type of field '_transform'. mangled type name is 'q_7ElementSTQzc'
in Xcode 10.0/Swift 4.2 playground– CRD
Nov 16 '18 at 11:08
What version of Xcode/Swift are you using? Commenting out your error at the end and running produces output at expected plus
SWIFT RUNTIME BUG: unable to demangle type of field '_transform'. mangled type name is 'q_7ElementSTQzc'
in Xcode 10.0/Swift 4.2 playground– CRD
Nov 16 '18 at 11:08
1
1
I think one thing you are missing is that in
encodeTransformDecode(transform: prefixesInt)
there is an implicit self
reference as prefixesInt
is an instance method – and in this case that self
is not of type [Int]
. This gives you two problems, wrong type, and even if it was the right type you've implicitly bound the self
. If you define a static
prefixesInt
method which takes an [Int]
and simply calls the instance version on its arg, pass that to encodeTransformDecode
, you'll get further. (I've got your code "working" in 10.0 but its spewing RUNTIME BUGs so won't post!)– CRD
Nov 16 '18 at 11:49
I think one thing you are missing is that in
encodeTransformDecode(transform: prefixesInt)
there is an implicit self
reference as prefixesInt
is an instance method – and in this case that self
is not of type [Int]
. This gives you two problems, wrong type, and even if it was the right type you've implicitly bound the self
. If you define a static
prefixesInt
method which takes an [Int]
and simply calls the instance version on its arg, pass that to encodeTransformDecode
, you'll get further. (I've got your code "working" in 10.0 but its spewing RUNTIME BUGs so won't post!)– CRD
Nov 16 '18 at 11:49
|
show 4 more comments
2 Answers
2
active
oldest
votes
As indicated in my comment and you've explored in your own answer, the core problem in your code is that you had the type of prefixesInt
incorrect. An instance method has a type of the form:
(<object type>) -> (<argument types>) -> <return type>
the value passed for <object type>
is what is bound to self
in the function. So the type prefixesInt
is:
([Int]) -> () -> AnyIterator<[Int]>
To fix your code you only need to change prefixes2
:
func prefixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]>
{
return encodeTransformDecode(transform: { $0.prefixesInt() } )
}
The type has changed to include AnyIterator<[Int]>
rather than AnyIterator<[Element]>
and a closure { $0.prefixesInt() }
is passed rather than just prefixesInt
(The former takes the array as argument while the compiler passes the latter, which is a shorthand for self.prefixesInt
, as a closure with the current value of self
pre-bound – that self
being the Array<Equatable>
prefixes2
was called on).
HTH
To see the connection with the code you produced consider that:
<value>.method(<args>)
is just a shorthand for:
<type of value>.method(<value>)(<args>)
Which in this case means that:
$0.prefixesInt()
is a shorthand for:
Array<Int>.prefixesInt($0)()
which is what you produced but distributed between prefixes()
(Array<Int>.prefixesInt
) and encodeTransformDecode
(transform(encode())()
). By using the shorthand and passing the closure no changes to encodeTransformDecode
are required.
Thanks CRD. Your answer really clarifies my understanding further. Much appreciated.
– Adahus
Nov 16 '18 at 23:20
add a comment |
With the help of useful nudges from @Carpsen90 and @CRD (thanks both!) and some dipping into the excellent book "obj Functional Swift" (No personal connection) I worked out a solution.
The type of an instance method is different from a static method as shown by:
extension Int {
static func doubleStatic(_ x: Int) -> Int { return x * 2 }
func doubleInstance() -> Int { return self * 2 }
}
print( type(of: Int.doubleStatic) ) // Prints: (Int) -> Int
print( type(of: Int.doubleInstance) ) // Prints: (Int) -> () -> Int
In the question the type of prefixesInt
is in fact: (Array<Int>) -> () -> AnyIterator<[Int]>
.
With this in mind we can rewrite encodeTransformDecode
as follows:
extension Array where Element: Equatable {
func encodeTransformDecode(transform: (Array<Int>) -> () -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode())().lazy.map { $0.decode(self) }
}
}
Secondly we need to tell the Compiler a bit more about the type of prefixesInt
when we use it in prefixes2
so:
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encodeTransformDecode(transform: Array<Int>.prefixesInt)
}
}
and now as required:
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
gives us:
["A"]
["A", "B"]
["A", "B", "C"]
and now very easily we can extend with other function very succinctly:
extension Array where Element == Int {
func suffixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.suffix(length))
}
}
}
extension Array where Element: Equatable {
func suffixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encodeTransformDecode(transform: Array<Int>.suffixesInt)
}
}
for suffix in ["A","B","C"].suffixes2() {
print(suffix)
}
Arguably the phrase:transform(encode())().lazy.map { $0.decode(self) }
is cryptic and might be better as:let encoded = encode()
let transformFunction = transform(encoded)
let transformIterator = transformFunction()
let lazyTransformIterator = transformIterator.lazy
return lazyTransformIterator.map { $0.decode(self) }
– Adahus
Nov 16 '18 at 20:07
add a comment |
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',
autoActivateHeartbeat: false,
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53335355%2farrayelement-is-not-convertible-to-arrayint%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
As indicated in my comment and you've explored in your own answer, the core problem in your code is that you had the type of prefixesInt
incorrect. An instance method has a type of the form:
(<object type>) -> (<argument types>) -> <return type>
the value passed for <object type>
is what is bound to self
in the function. So the type prefixesInt
is:
([Int]) -> () -> AnyIterator<[Int]>
To fix your code you only need to change prefixes2
:
func prefixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]>
{
return encodeTransformDecode(transform: { $0.prefixesInt() } )
}
The type has changed to include AnyIterator<[Int]>
rather than AnyIterator<[Element]>
and a closure { $0.prefixesInt() }
is passed rather than just prefixesInt
(The former takes the array as argument while the compiler passes the latter, which is a shorthand for self.prefixesInt
, as a closure with the current value of self
pre-bound – that self
being the Array<Equatable>
prefixes2
was called on).
HTH
To see the connection with the code you produced consider that:
<value>.method(<args>)
is just a shorthand for:
<type of value>.method(<value>)(<args>)
Which in this case means that:
$0.prefixesInt()
is a shorthand for:
Array<Int>.prefixesInt($0)()
which is what you produced but distributed between prefixes()
(Array<Int>.prefixesInt
) and encodeTransformDecode
(transform(encode())()
). By using the shorthand and passing the closure no changes to encodeTransformDecode
are required.
Thanks CRD. Your answer really clarifies my understanding further. Much appreciated.
– Adahus
Nov 16 '18 at 23:20
add a comment |
As indicated in my comment and you've explored in your own answer, the core problem in your code is that you had the type of prefixesInt
incorrect. An instance method has a type of the form:
(<object type>) -> (<argument types>) -> <return type>
the value passed for <object type>
is what is bound to self
in the function. So the type prefixesInt
is:
([Int]) -> () -> AnyIterator<[Int]>
To fix your code you only need to change prefixes2
:
func prefixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]>
{
return encodeTransformDecode(transform: { $0.prefixesInt() } )
}
The type has changed to include AnyIterator<[Int]>
rather than AnyIterator<[Element]>
and a closure { $0.prefixesInt() }
is passed rather than just prefixesInt
(The former takes the array as argument while the compiler passes the latter, which is a shorthand for self.prefixesInt
, as a closure with the current value of self
pre-bound – that self
being the Array<Equatable>
prefixes2
was called on).
HTH
To see the connection with the code you produced consider that:
<value>.method(<args>)
is just a shorthand for:
<type of value>.method(<value>)(<args>)
Which in this case means that:
$0.prefixesInt()
is a shorthand for:
Array<Int>.prefixesInt($0)()
which is what you produced but distributed between prefixes()
(Array<Int>.prefixesInt
) and encodeTransformDecode
(transform(encode())()
). By using the shorthand and passing the closure no changes to encodeTransformDecode
are required.
Thanks CRD. Your answer really clarifies my understanding further. Much appreciated.
– Adahus
Nov 16 '18 at 23:20
add a comment |
As indicated in my comment and you've explored in your own answer, the core problem in your code is that you had the type of prefixesInt
incorrect. An instance method has a type of the form:
(<object type>) -> (<argument types>) -> <return type>
the value passed for <object type>
is what is bound to self
in the function. So the type prefixesInt
is:
([Int]) -> () -> AnyIterator<[Int]>
To fix your code you only need to change prefixes2
:
func prefixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]>
{
return encodeTransformDecode(transform: { $0.prefixesInt() } )
}
The type has changed to include AnyIterator<[Int]>
rather than AnyIterator<[Element]>
and a closure { $0.prefixesInt() }
is passed rather than just prefixesInt
(The former takes the array as argument while the compiler passes the latter, which is a shorthand for self.prefixesInt
, as a closure with the current value of self
pre-bound – that self
being the Array<Equatable>
prefixes2
was called on).
HTH
To see the connection with the code you produced consider that:
<value>.method(<args>)
is just a shorthand for:
<type of value>.method(<value>)(<args>)
Which in this case means that:
$0.prefixesInt()
is a shorthand for:
Array<Int>.prefixesInt($0)()
which is what you produced but distributed between prefixes()
(Array<Int>.prefixesInt
) and encodeTransformDecode
(transform(encode())()
). By using the shorthand and passing the closure no changes to encodeTransformDecode
are required.
As indicated in my comment and you've explored in your own answer, the core problem in your code is that you had the type of prefixesInt
incorrect. An instance method has a type of the form:
(<object type>) -> (<argument types>) -> <return type>
the value passed for <object type>
is what is bound to self
in the function. So the type prefixesInt
is:
([Int]) -> () -> AnyIterator<[Int]>
To fix your code you only need to change prefixes2
:
func prefixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]>
{
return encodeTransformDecode(transform: { $0.prefixesInt() } )
}
The type has changed to include AnyIterator<[Int]>
rather than AnyIterator<[Element]>
and a closure { $0.prefixesInt() }
is passed rather than just prefixesInt
(The former takes the array as argument while the compiler passes the latter, which is a shorthand for self.prefixesInt
, as a closure with the current value of self
pre-bound – that self
being the Array<Equatable>
prefixes2
was called on).
HTH
To see the connection with the code you produced consider that:
<value>.method(<args>)
is just a shorthand for:
<type of value>.method(<value>)(<args>)
Which in this case means that:
$0.prefixesInt()
is a shorthand for:
Array<Int>.prefixesInt($0)()
which is what you produced but distributed between prefixes()
(Array<Int>.prefixesInt
) and encodeTransformDecode
(transform(encode())()
). By using the shorthand and passing the closure no changes to encodeTransformDecode
are required.
edited Nov 18 '18 at 12:38
answered Nov 16 '18 at 22:35
CRDCRD
45.3k44972
45.3k44972
Thanks CRD. Your answer really clarifies my understanding further. Much appreciated.
– Adahus
Nov 16 '18 at 23:20
add a comment |
Thanks CRD. Your answer really clarifies my understanding further. Much appreciated.
– Adahus
Nov 16 '18 at 23:20
Thanks CRD. Your answer really clarifies my understanding further. Much appreciated.
– Adahus
Nov 16 '18 at 23:20
Thanks CRD. Your answer really clarifies my understanding further. Much appreciated.
– Adahus
Nov 16 '18 at 23:20
add a comment |
With the help of useful nudges from @Carpsen90 and @CRD (thanks both!) and some dipping into the excellent book "obj Functional Swift" (No personal connection) I worked out a solution.
The type of an instance method is different from a static method as shown by:
extension Int {
static func doubleStatic(_ x: Int) -> Int { return x * 2 }
func doubleInstance() -> Int { return self * 2 }
}
print( type(of: Int.doubleStatic) ) // Prints: (Int) -> Int
print( type(of: Int.doubleInstance) ) // Prints: (Int) -> () -> Int
In the question the type of prefixesInt
is in fact: (Array<Int>) -> () -> AnyIterator<[Int]>
.
With this in mind we can rewrite encodeTransformDecode
as follows:
extension Array where Element: Equatable {
func encodeTransformDecode(transform: (Array<Int>) -> () -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode())().lazy.map { $0.decode(self) }
}
}
Secondly we need to tell the Compiler a bit more about the type of prefixesInt
when we use it in prefixes2
so:
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encodeTransformDecode(transform: Array<Int>.prefixesInt)
}
}
and now as required:
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
gives us:
["A"]
["A", "B"]
["A", "B", "C"]
and now very easily we can extend with other function very succinctly:
extension Array where Element == Int {
func suffixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.suffix(length))
}
}
}
extension Array where Element: Equatable {
func suffixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encodeTransformDecode(transform: Array<Int>.suffixesInt)
}
}
for suffix in ["A","B","C"].suffixes2() {
print(suffix)
}
Arguably the phrase:transform(encode())().lazy.map { $0.decode(self) }
is cryptic and might be better as:let encoded = encode()
let transformFunction = transform(encoded)
let transformIterator = transformFunction()
let lazyTransformIterator = transformIterator.lazy
return lazyTransformIterator.map { $0.decode(self) }
– Adahus
Nov 16 '18 at 20:07
add a comment |
With the help of useful nudges from @Carpsen90 and @CRD (thanks both!) and some dipping into the excellent book "obj Functional Swift" (No personal connection) I worked out a solution.
The type of an instance method is different from a static method as shown by:
extension Int {
static func doubleStatic(_ x: Int) -> Int { return x * 2 }
func doubleInstance() -> Int { return self * 2 }
}
print( type(of: Int.doubleStatic) ) // Prints: (Int) -> Int
print( type(of: Int.doubleInstance) ) // Prints: (Int) -> () -> Int
In the question the type of prefixesInt
is in fact: (Array<Int>) -> () -> AnyIterator<[Int]>
.
With this in mind we can rewrite encodeTransformDecode
as follows:
extension Array where Element: Equatable {
func encodeTransformDecode(transform: (Array<Int>) -> () -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode())().lazy.map { $0.decode(self) }
}
}
Secondly we need to tell the Compiler a bit more about the type of prefixesInt
when we use it in prefixes2
so:
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encodeTransformDecode(transform: Array<Int>.prefixesInt)
}
}
and now as required:
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
gives us:
["A"]
["A", "B"]
["A", "B", "C"]
and now very easily we can extend with other function very succinctly:
extension Array where Element == Int {
func suffixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.suffix(length))
}
}
}
extension Array where Element: Equatable {
func suffixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encodeTransformDecode(transform: Array<Int>.suffixesInt)
}
}
for suffix in ["A","B","C"].suffixes2() {
print(suffix)
}
Arguably the phrase:transform(encode())().lazy.map { $0.decode(self) }
is cryptic and might be better as:let encoded = encode()
let transformFunction = transform(encoded)
let transformIterator = transformFunction()
let lazyTransformIterator = transformIterator.lazy
return lazyTransformIterator.map { $0.decode(self) }
– Adahus
Nov 16 '18 at 20:07
add a comment |
With the help of useful nudges from @Carpsen90 and @CRD (thanks both!) and some dipping into the excellent book "obj Functional Swift" (No personal connection) I worked out a solution.
The type of an instance method is different from a static method as shown by:
extension Int {
static func doubleStatic(_ x: Int) -> Int { return x * 2 }
func doubleInstance() -> Int { return self * 2 }
}
print( type(of: Int.doubleStatic) ) // Prints: (Int) -> Int
print( type(of: Int.doubleInstance) ) // Prints: (Int) -> () -> Int
In the question the type of prefixesInt
is in fact: (Array<Int>) -> () -> AnyIterator<[Int]>
.
With this in mind we can rewrite encodeTransformDecode
as follows:
extension Array where Element: Equatable {
func encodeTransformDecode(transform: (Array<Int>) -> () -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode())().lazy.map { $0.decode(self) }
}
}
Secondly we need to tell the Compiler a bit more about the type of prefixesInt
when we use it in prefixes2
so:
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encodeTransformDecode(transform: Array<Int>.prefixesInt)
}
}
and now as required:
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
gives us:
["A"]
["A", "B"]
["A", "B", "C"]
and now very easily we can extend with other function very succinctly:
extension Array where Element == Int {
func suffixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.suffix(length))
}
}
}
extension Array where Element: Equatable {
func suffixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encodeTransformDecode(transform: Array<Int>.suffixesInt)
}
}
for suffix in ["A","B","C"].suffixes2() {
print(suffix)
}
With the help of useful nudges from @Carpsen90 and @CRD (thanks both!) and some dipping into the excellent book "obj Functional Swift" (No personal connection) I worked out a solution.
The type of an instance method is different from a static method as shown by:
extension Int {
static func doubleStatic(_ x: Int) -> Int { return x * 2 }
func doubleInstance() -> Int { return self * 2 }
}
print( type(of: Int.doubleStatic) ) // Prints: (Int) -> Int
print( type(of: Int.doubleInstance) ) // Prints: (Int) -> () -> Int
In the question the type of prefixesInt
is in fact: (Array<Int>) -> () -> AnyIterator<[Int]>
.
With this in mind we can rewrite encodeTransformDecode
as follows:
extension Array where Element: Equatable {
func encodeTransformDecode(transform: (Array<Int>) -> () -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode())().lazy.map { $0.decode(self) }
}
}
Secondly we need to tell the Compiler a bit more about the type of prefixesInt
when we use it in prefixes2
so:
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encodeTransformDecode(transform: Array<Int>.prefixesInt)
}
}
and now as required:
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
gives us:
["A"]
["A", "B"]
["A", "B", "C"]
and now very easily we can extend with other function very succinctly:
extension Array where Element == Int {
func suffixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.suffix(length))
}
}
}
extension Array where Element: Equatable {
func suffixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encodeTransformDecode(transform: Array<Int>.suffixesInt)
}
}
for suffix in ["A","B","C"].suffixes2() {
print(suffix)
}
answered Nov 16 '18 at 20:02
AdahusAdahus
650718
650718
Arguably the phrase:transform(encode())().lazy.map { $0.decode(self) }
is cryptic and might be better as:let encoded = encode()
let transformFunction = transform(encoded)
let transformIterator = transformFunction()
let lazyTransformIterator = transformIterator.lazy
return lazyTransformIterator.map { $0.decode(self) }
– Adahus
Nov 16 '18 at 20:07
add a comment |
Arguably the phrase:transform(encode())().lazy.map { $0.decode(self) }
is cryptic and might be better as:let encoded = encode()
let transformFunction = transform(encoded)
let transformIterator = transformFunction()
let lazyTransformIterator = transformIterator.lazy
return lazyTransformIterator.map { $0.decode(self) }
– Adahus
Nov 16 '18 at 20:07
Arguably the phrase:
transform(encode())().lazy.map { $0.decode(self) }
is cryptic and might be better as: let encoded = encode()
let transformFunction = transform(encoded)
let transformIterator = transformFunction()
let lazyTransformIterator = transformIterator.lazy
return lazyTransformIterator.map { $0.decode(self) }
– Adahus
Nov 16 '18 at 20:07
Arguably the phrase:
transform(encode())().lazy.map { $0.decode(self) }
is cryptic and might be better as: let encoded = encode()
let transformFunction = transform(encoded)
let transformIterator = transformFunction()
let lazyTransformIterator = transformIterator.lazy
return lazyTransformIterator.map { $0.decode(self) }
– Adahus
Nov 16 '18 at 20:07
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53335355%2farrayelement-is-not-convertible-to-arrayint%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
2
prefixesInt
is only defined onArray where Element == Int
and not arrays in general– ielyamani
Nov 16 '18 at 10:26
But encodeTransformDecode's signature is asking that transform has type: ([Int]) -> AnyIterator<[Int]> so not clear on the message?
– Adahus
Nov 16 '18 at 10:54
1
You can't call
prefixesInt
from an array where the only constraint on element is to be equatable. Plus the signature ofprefixesInt
is not([Int]) -> AnyIterator<[Int]>
– ielyamani
Nov 16 '18 at 10:58
What version of Xcode/Swift are you using? Commenting out your error at the end and running produces output at expected plus
SWIFT RUNTIME BUG: unable to demangle type of field '_transform'. mangled type name is 'q_7ElementSTQzc'
in Xcode 10.0/Swift 4.2 playground– CRD
Nov 16 '18 at 11:08
1
I think one thing you are missing is that in
encodeTransformDecode(transform: prefixesInt)
there is an implicitself
reference asprefixesInt
is an instance method – and in this case thatself
is not of type[Int]
. This gives you two problems, wrong type, and even if it was the right type you've implicitly bound theself
. If you define astatic
prefixesInt
method which takes an[Int]
and simply calls the instance version on its arg, pass that toencodeTransformDecode
, you'll get further. (I've got your code "working" in 10.0 but its spewing RUNTIME BUGs so won't post!)– CRD
Nov 16 '18 at 11:49