假设我有一个方法,它把一个(两个元素上的函数)变成一个(两个序列上的函数):
def seqed[T](f: (T,T) => T): (Seq[T], Seq[T]) => Seq[T] = (_,_).zipped map f换句话说,生成的函数接受两个序列xs和ys,并创建一个由(xs(0) f ys(0), xs(1) f ys(1), ...)组成的新序列,因此,例如,如果xss为Seq(Seq(1,2),Seq(3,4)),f为(a: Int, b: Int) => a + b,我们可以这样调用它:
xss reduceLeft seqed(f) // Seq(4, 6)或者使用匿名函数:
xss reduceLeft seqed[Int](_+_)这很好;摆脱[Int]类型参数会很好,但我不知道怎么做(有什么想法吗?)
为了让它看起来更像tupled方法,我还尝试了enrich-my-library模式:
class SeqFunction[T](f: (T,T) => T) {
def seqed: (Seq[T], Seq[T]) => Seq[T] = (_,_).zipped map f
}
implicit def seqFunction[T](f: (T,T) => T) = new SeqFunction(f)对于一个预定义的函数,它工作得很好,但是对于匿名函数来说就不太好用了
xss reduceLeft f.seqed
xss reduceLeft ((_:Int) + (_:Int)).seqed有没有其他方法可以重新表述,以便推断类型,并使用类似以下的语法:
// pseudocode
xss reduceLeft (_+_).seqed // ... or failing that
xss reduceLeft (_+_).seqed[Int]?或者我对类型推断的要求太高了?
发布于 2011-12-04 11:36:14
中需要类型批注的原因
xss reduceLeft seqed[Int](_+_)但不是在
xs zip ys map Function.tupled(_+_)这是由于map和reduceLeft的类型要求不同造成的。
def reduceLeft [B >: A] (f: (B, A) ⇒ B): B
def map [B] (f: (A) ⇒ B): Seq[B] // simple version!reduceLeft期望seqed返回类型B,其中B >: Int。因此,似乎无法知道seqed的确切类型,因此我们必须提供注释。有关更多信息,请访问this question。
克服这个问题的一种方法是在没有下限的情况下重新实现reduceLeft。
implicit def withReduceL[T](xs: Seq[T]) = new {
def reduceL(f: (T, T) => T) = xs reduceLeft f
}测试:
scala> Seq(Seq(1,2,3), Seq(2,2,2)) reduceL seqed(_+_)
res1: Seq[Int] = List(3, 4, 5)现在的问题是,无论有没有[Int]参数,这在Seq的子类型(例如List)上都不起作用:
scala> Seq(List(1,2,3), List(2,2,2)) reduceL seqed(_+_)
<console>:11: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2))
Seq(List(1,2,3), List(2,2,2)) reduceL seqed(_+_)
^reduceL需要(List[Int], List[Int]) => List[Int]类型的函数。因为Function2被定义为Function2 [-T1, -T2, +R],所以(Seq[Int], Seq[Int]) => Seq[Int]不是有效的替换。
发布于 2011-12-01 05:24:20
你不能按你想要的方式去做,但是看看Function.tupled,它是.tupled的对立面,它解决了同样的问题。
scala> List(1, 2, 3) zip List(1, 2, 3) map (_ + _).tupled
<console>:8: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2))
List(1, 2, 3) zip List(1, 2, 3) map (_ + _).tupled
^
<console>:8: error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$plus(x$2))
List(1, 2, 3) zip List(1, 2, 3) map (_ + _).tupled
^
scala> List(1, 2, 3) zip List(1, 2, 3) map Function.tupled(_ + _)
res7: List[Int] = List(2, 4, 6)发布于 2011-12-01 02:36:45
我很确定你的要求太高了。Scala goes from left to right中的类型推断,所以在考虑.sedeq部分之前,首先需要弄清楚(_+_)的类型。而且那里没有足够的信息。
https://stackoverflow.com/questions/8328748
复制相似问题