2013-02-14 55 views
1

我想在Scala中编译简单的helloworld, 并获得错误“scala:value capitalize is not char of member” 为什么编译器认为newW是Char?Scala:映射字符串时出现错误的类型推断?

val dict = Map(
    "hello" -> "olleh", 
    "world" -> "dlrow" 
) 

def translate(input: String): String = { 
    input.split("""\s+""").map(w => dict.getOrElse(w.toLowerCase, w).map(newW => 
    (if (w(0).isUpper) newW.capitalize else newW)) 
).mkString(" ") 
} 

回答

3

translatemap第二个电话是对面dict.getOrElse(...)返回的值,其类型为String,它可以作为一个Iterable[Char]被隐式处理映射。因此,编译器正确地推断出newW的类型为Char,并且当您尝试对其调用capitalize时抱怨。你可能寻找的东西沿着

def translate(input: String): String = { 
    input.split("""\s+""").map(w => { 
    val newW = dict.getOrElse(w.toLowerCase, w) 
    (if (w(0).isUpper) newW.capitalize else newW) 
    }).mkString(" ") 
} 

更新的线路:顺便说一句,这将在运行时失败,如果input是一个空字符串 - 它需要安全的至少一个或多个检查。

+0

从技术上讲,不像Haskell,'String'不是'List [Char]'。我认为他们之间有一个隐含的转换。 – 2013-02-14 23:53:20

+0

你说得对,我已经相应地更新了文字。 – 2013-02-14 23:55:46

3

这里发生的事情:

input // is a string 
.split("""\s+""") // is an Array[String] 
.map(w => // w is a String, for each String in the Array[String] 
    dict.getOrElse(w.toLowerCase, w) // is a String (returned by dict.getOrElse) 
    .map(newW => // is a Char, for each Char in the String returned by dict.getOrElse