Recursive generic listings in Swift

I am new to Swift. I tried to implement a binary tree with recursive enums and generics:

enum BinaryTree<T> { indirect case Node(T, BinaryTree<T>, BinaryTree<T>) case Nothing } func inorder<T>(_ root: BinaryTree<T>) -> [T] { switch root { case .Nothing: return [] case let .Node(val, left, right): return inorder(left) + [val] + inorder(right) } } 

Here is the error I received:

 $ swift ADT.swift ADT.swift:83:20: error: cannot convert value of type 'BinaryTree<T>' to expected argument type 'BinaryTree<_>' return inorder(left) + [val] + inorder(right) ^~~~ 

However, this works:

 func inorder<T>(_ root: BinaryTree<T>) -> [T] { switch root { case .Nothing: return [] case let .Node(val, left, right): let l = inorder(left) let r = inorder(right) return l + [val] + r } } 

Are there any errors in my syntax? Thanks!

I am using Swift 3.0.

+5
source share
1 answer

Update
Therefore, I tried to reduce the problem to the minimum approximate code that could not be compiled, and I asked the question myself and filed SR-4304 . Turns out the answer is that this is really a compiler error.

Original answer
As far as I can tell, your syntax is perfectly correct. It seems like swift type output for compilers seems to need a push in the right direction, which apparently provides your second solution. Since I had several similar problems in the past, especially regarding the + operator, your question prompted me to try several other ways to join arrays. All of these work (I just show the return statements and supporting functions for the last three cases):

 return (inorder(left) as [T]) + [val] + inorder(right) return Array([inorder(left), [val], inorder(right)].joined()) return [inorder(left), [val], inorder(right)].reduce([], +) return [inorder(left), [val], inorder(right)].flatMap { $0 } func myjoin1<T>(_ arrays: [T]...) -> [T] { return arrays.reduce([], +) } return myjoin1(inorder(left), [val], inorder(right)) func myjoin2<T>(_ array1: [T], _ array2: [T], _ array3: [T]) -> [T] { return array1 + array2 + array3 } return myjoin2(inorder(left), [val], inorder(right)) extension Array { func appending(_ array: [Element]) -> [Element] { return self + array } } return inorder(left).appending([val]).appending(inorder(right)) 

An operator call as a function also compiles:

 return (+)(inorder(left), [val]) + inorder(right) 

It would be great if someone with a deeper knowledge of the Swift compiler could shed some light on this.

+1
source

Source: https://habr.com/ru/post/1257601/


All Articles