数字类型的 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
函数,例如 sum
、prod
、min
、max
,将 List[T]
转换为a T
其中 T
是数字。
设计可能看起来做作,但我 interop-ing 和 Java。更具体地说,使用 Java.
编写的 Hadoop 库
我需要编写一个函数来接收将 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
函数,例如 sum
、prod
、min
、max
,将 List[T]
转换为a T
其中 T
是数字。
设计可能看起来做作,但我 interop-ing 和 Java。更具体地说,使用 Java.
编写的 Hadoop 库