Jos*_*man 10 scala structural-typing
我正在尝试定义一个结构类型,定义任何具有"add"方法的集合(例如,java集合).使用这个,我想定义一些对某个集合进行操作的高阶函数
object GenericTypes {
type GenericCollection[T] = { def add(value: T): java.lang.Boolean}
}
import GenericTypes._
trait HigherOrderFunctions[T, CollectionType[X] <: GenericCollection[X]] {
def map[V](fn: (T) => V): CollectionType[V]
....
}
class RichJList[T](list: List[T]) extends HigherOrderFunctions[T, java.util.List]
Run Code Online (Sandbox Code Playgroud)
这不会编译与以下错误
error: Parameter type in structural refinement may not refer to abstract type defined outside that same refinement
Run Code Online (Sandbox Code Playgroud)
我尝试删除GenericCollection上的参数并将其放在方法上:
object GenericTypes {
type GenericCollection = { def add[T](value: T): java.lang.Boolean}
}
import GenericTypes._
trait HigherOrderFunctions[T, CollectionType[X] <: GenericCollection]
class RichJList[T](list: List[T]) extends HigherOrderFunctions[T, java.util.List]
Run Code Online (Sandbox Code Playgroud)
但我得到另一个错误:
error: type arguments [T,java.util.List] do not conform to trait HigherOrderFunctions's type parameter bounds [T,CollectionType[X] <: org.scala_tools.javautils.j2s.GenericTypes.GenericCollection]
Run Code Online (Sandbox Code Playgroud)
谁能给我一些关于如何在Scala中使用抽象类型参数进行结构化输入的建议?或者如何实现我想要实现的目标?非常感谢!
正如您在票证 1906中看到的,由于运行时缺少类型信息,您无法使用结构类型外部定义的抽象类型。
Scala 语言参考 (3.2.7 复合类型)中对此进行了说明:
Within a method declaration in a structural refinement, the type of
any value parameter may only refer to type parameters or abstract types that are
contained inside the refinement.
Run Code Online (Sandbox Code Playgroud)
向类型添加新方法的常用方法是通过隐式类型转换。
trait HigherOrderFunctions[T, CC[_]] {
def zap[V](fn: () => V): CC[V]
}
class RichJList[T](list: java.util.List[T]) extends HigherOrderFunctions[T, java.util.List]{
def zap[V](fn: () => V): java.util.List[V] = {
val l = new java.util.ArrayList[V]
l add fn()
l
}
}
implicit def list2RichList[T](l : java.util.List[T]) = new RichJList(l)
new java.util.ArrayList[AnyRef]() zap (() => 2)
Run Code Online (Sandbox Code Playgroud)
如果编译器发现该类型错过了 zap 方法,它会将其转换为具有 zap 方法的类型,并且在范围内具有隐式转换方法(此处为 list2RichList)。
scala> new java.util.ArrayList[AnyRef]() zap (() => 2)
res0: java.util.List[Int] = [2]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1952 次 |
| 最近记录: |