1

このスニペットが出力されないのはなぜですか: 「関数の実装に成功しました」

詳細:

val actual の型が List[Either[List[Int], Int]] 型のように見えるのはなぜですか?

// Flatten a nested list structure

def flatten[T](list: List[Either[List[T], T]]): List[T] = list flatMap {
    // TODO: Implement
    case list: List[T]  => list
    case element: T     => List(element)
}

implicit def ElementToEitherLeft[T](obj: T) = Left(obj)
implicit def ElementToEitherRight[T](obj: T) = Right(obj)

val list: List[Either[List[Int], Int]] = List(List(1, 1), 2, List(3, 5))
val actual: List[Int] = flatten[Int](list)
val expected = List(1, 1, 2, 3, 5)
if (actual == expected)     print("You successfully implemented the function")
else                        print("Unfortunatly, that's not quite rigth yet")
4

2 に答える 2

7

コンパイルすると、flatten次のような警告が表示されるはずです。

warning: there were 2 unchecked warnings; re-run with -unchecked for details

でコンパイルした場合は、次のように表示され-uncheckedます。

<console>:9: warning: non variable type-argument T in type pattern List[T] is unchecked since it is eliminated by erasure
           case list: List[T]  => list
                      ^
<console>:10: warning: abstract type T in type pattern T is unchecked since it is eliminated by erasure
           case element: T     => List(element)

要するに、あなたのためにflatMapあなたのアイテムをアンラップするつもりはありませEitherん、そしてあなたが書いたものは型消去とパターンマッチングについてのいくつかの不快な事実のためにコンパイルされるだけです。

幸い、簡単な修正があります。

 def flatten[T](list: List[Either[List[T], T]]): List[T] = list flatMap {
   case Left(list)  => list
   case Right(item) => item :: Nil
 }

または、さらに良い:

def flatten[T](list: List[Either[List[T], T]]): List[T] =
  list.flatMap(_.fold(identity, List(_)))

どちらも期待どおりに機能します。

于 2012-08-27T01:45:35.750 に答える
1

2.10 でコンパイルすると、次のような警告が表示されます。

<console>:7: warning: match may not be exhaustive.
It would fail on the following inputs: Left(_), Right(_)

2.10-M6 でコンパイルすると、次のような偽の警告も表示されます。

warning: unreachable code
case element: T     => List(element)

あなたが見たいのは、次のような警告です:

warning: unreachable code
case list: List[T]  => list

つまり、それは List[List] ではなく List[Either] ですが、現時点ではコンパイラが最善を尽くしています。

これらは、 でオフになっている警告です-Xno-patmat-analysis。11 まで上げるオプションはないようです。

型パラメーターを取り除くことで消去の警告をなくすことができます。これは自然なことですが、型システムからのサポートが得られず、到達可能性や一致の警告も得られません。

def flatten(list: List[Either[List[_], _]]): List[Any] = list flatMap {
  case list: List[_]  => list
  case element        => List(element)
}
于 2012-08-27T09:45:06.253 に答える