用丰富的我的图书馆键入匿名函数的推断
-
26-10-2019 - |
题
假设我有一种将(两个元素的函数)转换为(两个序列的函数)的方法:
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
方法,我还尝试了富集的图模式:
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]
?还是我问过多的类型推理?
解决方案 3
需要在
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
不知道,因此我们必须提供注释。更多信息 这个问题.
克服这一点的一种方法是重新实现 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)
现在的问题是,现在这对子类型不起作用 Seq
(例如 List
),有或没有 [Int]
范围:
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]
不是有效的替代。
其他提示
你不能按想要的方式做,但是看 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)
我很确定你 是 问太多。在Scala中输入推理 从左到右, ,所以 (_+_)
还需要先弄清楚,然后再考虑 .sedeq
部分。而且那里没有足够的信息。