2016-10-02 21 views
5

私はSwiftを初めて使っています。私は再帰的列挙し、ジェネリック医薬品とのバイナリツリーを実装しようとしていた。スウィフトのジェネリックスでの再帰的列挙

$ 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) 
        ^~~~ 

しかし、これは動作します:

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 
    } 
} 

間違いありここ

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) 
    } 
} 

私が得たエラーです私の構文では?ありがとう!

私はSwift 3.0を使用しています。

答えて

1

更新
だから私は、最小限の例のコンパイルに失敗したコードとasked a questionに自分自身で問題を凝縮しようとしたとSR-4304を提出しました。答えは、実際にはコンパイラのバグだということです。

元回答
私の知る限り、構文は完全に有効です。 Swiftコンパイラの型推論には、2番目の解決策が明らかに正しい方向に向かって動きが必要であるようです。過去にいくつかの同様の問題、特に+オペレータに関して経験したように、あなたの質問は、私がアレイに加わるためにいくつかの他の方法を試みるよう促しました。すべての作業(私はreturn文を示し、最後の3例のための機能をサポートしています)これらの:関数がコンパイルとして

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)) 

は、あまりにも、オペレーターを呼び出す:

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

をそれがあれば素晴らしいことですSwiftコンパイラについてのより深い知識を持つ誰かが、これについていくつかの光を当てることができました。

+0

ありがとうございます。興味深いことに、いくつかのソリューションでは、元のタイプ以外のタイプについての情報は提供されずにコンパイルされます。 –

+1

@ Kuan-Ying Chou:まあ、すべての解決策が共通しているのは、コンパイラが(埋め込み) '+ '演算子の連鎖使用のためにすべての型を推論する必要がないということです。コンパイラがコンパイルに失敗したため、バグとして確認されます。私はそれに応じて私の答えを更新しました。 – thm

関連する問題