Scala无形多态值函数用于数值类型

时间:2017-01-15 19:52:11

标签: scala generics shapeless

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

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

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

但我收到错误,因为无形期望函数为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))会返回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]]

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

看着无形的'代码我发现我可以执行以下操作:

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]转换为{ {1}}其中T是数字。

设计可能看似人为,但我正在与Java交互。更具体地说,使用Java编写的Hadoop库。