将 Scala 结构类型与抽象类型一起使用 [英] Using Scala structural types with abstract types

查看:36
本文介绍了将 Scala 结构类型与抽象类型一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试定义一个结构类型,该类型定义任何具有添加"方法的集合(例如,java 集合).使用这个,我想定义一些对某个集合进行操作的高阶函数

I'm trying to define a structural type defining any collection that has an "add" method (for instance, a java collection). Using this, I want to define a few higher order functions that operate on a certain collection

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]

这不会编译并出现以下错误

This does not compile with the following error

error: Parameter type in structural refinement may not refer to abstract type defined outside that same refinement 

我尝试删除 GenericCollection 上的参数并将其放在方法上:

I tried removing the parameter on GenericCollection and putting it on the method:

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]

但我收到另一个错误:

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]

谁能给我一些关于如何在 Scala 中使用带有抽象类型参数的结构类型的建议?或者如何实现我想要实现的目标?非常感谢!

Can anyone give me some advice on how to use structural typing with abstract typed parameters in Scala? Or how to achieve what I'm looking to accomplish? Thanks so much!

推荐答案

正如您在 ticket 1906 由于在运行时缺少类型信息,您不能使用在结构类型之外定义的抽象类型.

As you can see in ticket 1906 you can't use the abstract type defined outside the structural type due to missing type information at runtime.

这在 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.

向类型添加新方法的常用方法是通过隐式类型转换.

The usual way to add new methods to a type is by implicit type conversion.

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)

如果编译器发现该类型错过了 zap 方法,它会将其转换为具有 zap 方法的类型,并在范围内使用隐式转换方法(此处为 list2RichList).

If the compiler sees that the type missed the zap method it will convert it to a type that has the zap method with a implicit conversion method (here list2RichList) in scope.

scala> new java.util.ArrayList[AnyRef]() zap (() => 2)
res0: java.util.List[Int] = [2]

这篇关于将 Scala 结构类型与抽象类型一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆