2013-05-10 15 views
5

次のコードScalaのため、理解型推論

def f(chars: List[Char]): List[List[Char]] = chars match { 
    case Nil => List(Nil) 
    case x :: xs => for { 
     v <- f(xs) 
    } yield List(x) :: v 
    } 

は、エラーメッセージ

- type mismatch; found : List[List[Any]] required: List[List[Char]] 

を与えるには、「の」のここでの任意の代わりにシャアの最も一般的に選択した理由を私は理解して助けてください?言語仕様のどのトピックを読んでください。ありがとう。

答えて

10

yieldingは、List[List[List[Char]]]List[List[Char]]の組み合わせです。 ScalaはそれをList[List[Any]]にアップキャストします。あなたのケースについては、以下のいずれかの作業を行います。

scala> def f(chars: List[Char]): List[List[Char]] = chars match { 
    |  case Nil => List(Nil) 
    |  case x :: xs => for { 
    |  v <- f(xs) 
    |  } yield x :: v 
    | } 
f: (chars: List[Char])List[List[Char]] 

scala> def f(chars: List[Char]): List[List[Char]] = chars match { 
    |  case Nil => List(Nil) 
    |  case x :: xs => for { 
    |  v <- f(xs) 
    |  } yield List(x) ++ v 
    | } 
f: (chars: List[Char])List[List[Char]] 
6

問題がList(x)ある - それはxにする必要があります。

vは、f(xs)の結果を反復し、fList[List[Char]]を返します。つまり、結果はList[X]になります。Xyieldによって返されるタイプです。

vのタイプは、f(xs)の内容を反復しているので、List[Char]です。だから我々はタイプList[Char]の上にList[Char]の前にあるList(x) :: vのタイプを把握しなければならない。 ではなく、を連結しています。文字のみを含むリストにリストを追加しています。結果リストにはCharList[Char]の両方が含まれます。

両方を満たす唯一のタイプがAnyであるため、XAnyとなり、理解の結果List[Any]となります。