我是 Scala 的新手。我有一个Class A
那个。我也有那个也有extends
Class C
Class B
extends
Class C
我希望类型的函数对象也A->B
能够扩展C
(以及其他派生类型,例如A->(A->B)
)。但我在“Scala 编程”中读到:
函数文字被编译成一个类,在运行时实例化时是一个函数值。
是否有某种方法可以自动让A->B
extend
C
,然后手动创建一个代表该函数的新类?
我是 Scala 的新手。我有一个Class A
那个。我也有那个也有extends
Class C
Class B
extends
Class C
我希望类型的函数对象也A->B
能够扩展C
(以及其他派生类型,例如A->(A->B)
)。但我在“Scala 编程”中读到:
函数文字被编译成一个类,在运行时实例化时是一个函数值。
是否有某种方法可以自动让A->B
extend
C
,然后手动创建一个代表该函数的新类?
Scala 中的函数是通过FunctionN
trait 建模的。例如,简单的一输入一输出函数都是以下特征的所有实例:
trait Function1[-T1, +R] extends AnyRef
所以你要问的是“我怎样才能让实例Function
也成为C
”的子类。这不能通过标准子类型化/继承来实现,因为显然我们无法修改Function1
trait 以使其扩展您的自定义类C
。当然,我们可以按照您的建议组成一个新类来表示该函数,但这只会带我们到此为止,而且实现起来并不容易,更不用说您要使用的任何函数 asC
都必须转换为首先是您的伪功能特征,这将使事情变得可怕。
然而,我们可以做的是创建一个类型类,然后包含一个实现A -> B
,等等。
我们以下面的代码为例:
trait A
trait B
trait C[T]
object C {
implicit val fa = new C[A] {}
implicit val fb = new C[B] {}
implicit val fab = new C[Function1[A, B]] {}
}
object Test extends scala.App {
val f: A => B = (a: A) => new B {}
def someMethod[Something: C](s: Something) = {
// uses "s", for example:
println(s)
}
someMethod(f) // Test$$$Lambda$6/1744347043@dfd3711
}
您尚未指定使 A -> B 扩展 C 的动机,但显然您希望能够将 A、B 和 A -> B 放在“同一个保护伞”下,因为您有某种方法(称为someMethod
)它采用C
继承方式,您可以将 A、B 或 A -> B 类型的值传递给它。
使用类型类,您可以实现相同的目标,并具有一些额外的优势,例如D
,在不更改现有代码的情况下添加到家族中(您只需要C[D]
在范围内的某处实现类型的隐式值)。
因此,它不是someMethod
获取 的实例C
,而是简单地获取某种类型的东西(我们称之为它s
)(我们称之为它),并带有必须存在Something
的约束。C[Something]
如果你传递了一个不存在 C 实例的东西,你会得到一个错误:
trait NotC
someMethod(new NotC {})
// Error: could not find implicit value for evidence parameter of type C[NotC]
你实现了同样的事情——你有一个家庭,C
其成员是A
,B
和A => B
,但是你解决了子类型化问题。