对我来说,这是一个相当普遍的情况:
trait CoVariant[+T] {
def bar: T
}
def curried[T](x: String)(y: CoVariant[T]) = y // Not really, but for simplicity
val applied = curried("foo") _
val bar = new CoVariant[String] {
def bar = "bar"
}
applied(bar)因此,我有一个协变的东西,我需要先做一些普通的事情,然后有一个通用的部分没有应用。我非常希望能够像上面那样编写它,但这当然会在最后一行产生编译错误:
- type mismatch; found : CoVariant[String] required: CoVariant[Nothing]我似乎只需要引入一个类,这样就可以将类型参数放在某个地方,这样就可以让它变得抽象起来:
trait StupidWrapper {
def apply[T](y: CoVariant[T]) : CoVariant[T]
}而不是咖喱的东西
def notAsNice(x: String) = new StupidWrapper {
def apply[T](y: CoVariant[T]) = y
}所以现在:
val applied = notAsNice("foo")
applied(bar) 编译。
这感觉很蠢,我想还有更好的方法吗?
更新:
我想我最好把它具体化。我所拥有的是:
abstract class ParserToSeq {
def apply[T](parser: Parser[T]): Seq[T]
}
def fromTrainingData(trainingLines: Seq[String]) = new ParserToSeq {
def apply[T](p: Parser[T]) = trainingLines.map(parseAll(p, _)).map {
_ match {
case Success(wt, _) => Some(wt)
case _ => None
}
}.flatten
}然后
val thisData = fromTrainingData(trainingLines)
lazy val wordTags = thisData(wordtagParser) // Parser[WordTag]
lazy val uniGrams = thisData(uniGramParser) // Parser[UniGram]
…我只想废除ParserToSeq,然后做:
def fromTrainingData[T](trainingLines: Seq[String])(p: Parser[T]) =
trainingLines.map(parseAll(p, _)).map {
_ match {
case Success(wt, _) => Some(wt)
case _ => None
}
}.flatten注意,这里的T对每个解析器都是特定的。据我理解,这个问题是,在部分应用的方法上,T被解决为一个具体的类型,即使类型实际上适用于第二个参数列表。
看来我想在中间的某个地方贴上这类对白的声明:
def fromTrainingData(trainingLines: Seq[String])[T](p: Parser[T])这当然不是有效的Scala。
发布于 2013-04-14 15:43:17
正如您提到的,scala Function对象don't carry type parameters。
但是,您可以将ParseToSeq替换为 that takes higher-kinded types,
trait ~>[A[_],B[_]] {
def apply[X](a : A[X]) : B[X]
}然后你的例子变成,
trait Parser[T]
trait WordTag
trait UniGram
val trainingLines: Seq[String] = ???
val wordtagParser: Parser[WordTag] = ???
val uniGramParser: Parser[UniGram] = ???
def fromTrainingData[T](trainingLines: Seq[String]) = new ~>[Parser,Seq] {
def apply[T](p: Parser[T]): Seq[T] = ???
}
val thisData = fromTrainingData(trainingLines)
lazy val wordTags = thisData(wordtagParser) // Seq[WordTag]
lazy val uniGrams = thisData(uniGramParser) // Seq[UniGram]https://stackoverflow.com/questions/16000251
复制相似问题