7

私は Scala の初心者で、型システムについて質問があります。

flatten メソッドはネストされたコレクションで機能するため、リストのリストがある場合、リストにフラット化されます。しかし、すでにフラットになっているコレクションに対して flatten を呼び出すのは意味がありません。そして、確かに Scala 型チェッカーはそれをエラーとしてフラグ付けします。

List(List(1,2,3),List(4,5,6)).flatten // produces List(1,2,3,4,5,6)
List(1,2,3,4).flatten  // type error

これはどういうわけか、平坦化する暗黙のパラメーターに依存していることを理解しています。しかし、暗黙的な値がどこから来ているのか、オブジェクトの型をアサートするためにそれがどのように使用されているのかはわかりません。また、暗黙のパラメーターが List.flatten の scaladocs に表示されないのはなぜですか?

4

2 に答える 2

4

これがどのように機能するかを理解するには、flatten の型シグネチャを確認する必要があります。

def flatten[B](implicit asTraversable: (A) ⇒ GenTraversableOnce[B]): List[B]

Aはリストの要素Bの型であり、各要素の要素の型です。flatten が機能するためには、要素型から への暗黙的な変換が必要GenTraversableOnce[B]です。これは、コレクションの場合、または独自の暗黙的な変換を実装する場合にのみ当てはまります。たとえば、ペアに対して 1 つを定義できます。

implicit def pairToList[A](p:(A,A)) = List(p._1, p._2)

List(1->2,2->3).flatten //compiles! List(1,2,2,3)
于 2012-10-24T14:38:19.433 に答える
1

トリックは、リスト内の要素がトラバース可能であることを保証する暗黙の証人です。GenericTraversableTemplateflattenから取得した (少し簡略化した) シグネチャを次に示します。

def flatten[B](implicit asTraversable: A => TraversableOnce[B])
              : GenTraversable[B] =

あなたの場合、 type の要素の証人が見つからないためInt、の呼び出しはflattenコンパイラによって拒否されます。


サンプルをコンパイルしたい場合は、次の暗黙の定義を使用できます。

implicit def singleToList[A](a: A) = List(a)

(補足として、このような暗黙的なものは非常に危険であると考えています。これは、その適用性が非常に一般的であり、コンパイラーが気付かないうちにさまざまな場所で呼び出しを挿入する可能性があるため、不愉快な驚きをもたらす可能性があるためです。)

于 2012-10-24T14:40:18.093 に答える