数字类型的 Scala 无形多态值函数

Scala shapeless polymorphic value function for numeric types

我需要编写一个函数来接收将 List[T] 转换为 T 的函数。比如对列表的元素求和。

我的第一个尝试是使用无形多态函数作为:

object sumPoly extends (List ~> Option) = {
  def apply[T: Numeric](list: List[T]): Option = Some(list.sum)
}

但我得到一个错误,因为 shapeless 期望函数是 def apply[T](...)

接收上述函数的函数如下所示:

def test(list: List[Any], f: (List ~> Option)) = {
  val intTypeCase = TypeCase[List[Int]]
  val doubleTypeCase = TypeCase[List[Double]]
  val longTypeCase = TypeCase[List[Long]]
  list match {
    intTypeCase(l) => f(l)
    doubleTypeCase(l) => f(l)
    longTypeCase(l) => f(l)
    // more type matchings here
  }
  ...
}

有没有办法实现我想做的事情?

编辑

经过一些搜索,我发现可以执行以下操作:

object sumPoly extends Poly1 {
  implicit def caseListInt = at[List[Int]](x => x.sum)
  implicit def caseListDouble = at[List[Double]](x => x.sum)
  // more type matchings here
}

并正确调用 sumPoly(List(1, 1, 1)) returns 3。但是如果我将 test 函数定义为:

def test(list: List[Any], f: Poly1) = {
  val intTypeCase = TypeCase[List[Int]]
  val doubleTypeCase = TypeCase[List[Double]]
  val longTypeCase = TypeCase[List[Long]]
  list match {
    intTypeCase(l) => f(l)
    doubleTypeCase(l) => f(l)
    longTypeCase(l) => f(l)
    // more type matchings here
  }
  ...
}

并传递 sumPoly 函数,对于我在 test 函数中定义的每种类型,我都会得到这样的错误:could not find implicit value for parameter cse: shapeless.poly.Case[f.type,shapeless.::[List[Int],shapeless.HNil]]

有什么想法吗?

通过查看 shapeless 的代码,我发现我可以执行以下操作:

object sumPoly extends Poly1 {
  implicit def caseList[T: Numeric] = at[List[T]] { x => x.sum }
}

然后将接收 Poly1 的函数必须具有以下定义:

def test(list: List[Any], f: Poly1) 
        (implicit li : f.Case[List[Int]], 
                  ld : f.Case[List[Double]], 
                  ll : f.Case[List[Long]])= {

  val intTypeCase = TypeCase[List[Int]]
  val doubleTypeCase = TypeCase[List[Double]]
  val longTypeCase = TypeCase[List[Long]]
  list match {
    intTypeCase(l) => f(l)
    doubleTypeCase(l) => f(l)
    longTypeCase(l) => f(l)
    // more type matchings here
  }
  ...
}

这样,我可以创建不同的 Poly1 函数,例如 sumprodminmax,将 List[T] 转换为a T 其中 T 是数字。

设计可能看起来做作,但我 interop-ing 和 Java。更具体地说,使用 Java.

编写的 Hadoop 库