类型不匹配的Scala链函数

类型不匹配的Scala链函数,scala,Scala,我有一系列函数,可以清理文本并将其拆分为单词。最简单的例子: val txt = "Mary had a @little \nlamb" val stopwords = Seq("a") def clean(text: String): String = text.replaceAll("\n*\r*", "") def tokenize(text: String): Seq[String] = text.split("\\s") val cleaned = clean(txt) val to

我有一系列函数,可以清理文本并将其拆分为单词。最简单的例子:

val txt = "Mary had a @little \nlamb"
val stopwords = Seq("a")
def clean(text: String): String = text.replaceAll("\n*\r*", "")
def tokenize(text: String): Seq[String] = text.split("\\s")

val cleaned = clean(txt)
val tokens = tokenize(cleaned)
此代码按预期工作。然而,这并不是真正的习惯用语。 我曾希望这样做:

clean(txt) andThen tokenize
但是编译器抱怨这是错误的
类型不匹配;必需:标记化函数处的Char=>?


我在这里遗漏了什么?

clean
返回一个
字符串
。您试图在
字符串
实例上使用
(因为您使用
clean(txt)
调用该方法),编译器将其推断为
PartialFunction[Char,?]
(因为
WrappedString
继承
AbstractSeq[Char]
,后者继承
PartialFunction[Char,a]
)。这就是为什么您会看到类型不匹配。如果要将两者组合在一起,请使用eta扩展将它们转换为函数类型:

val res = clean _ andThen tokenize
println(res(txt))

函数组合在Scala函数上工作,而不是在方法上工作(这是有区别的),这就是为什么我们必须首先将方法扩展到函数(
clean
),然后编译器将能够为我们推断
tokenize
,而无需手动扩展它。

有趣的是,我明白了。不知道埃塔的扩张。我有一些书要读:)。