我是Scala的新手。
我有一个Class A
extends
一个Class C
。我还有一个Class B
也extends
一个Class C
我希望类型A->B
的函数对象也可以扩展C
(以及其他派生类型,例如A->(A->B)
)。但我在下面的“scala编程”中读到:
函数文字被编译成一个在运行时实例化的类 是一个函数值。
是否有某种方法可以自动让A->B
extend
C
,然后手动创建一个代表该功能的新类?
答案 0 :(得分:2)
Scala中的函数通过FunctionN
特征建模。例如,简单的单输入一输出函数都是以下特征的实例:
trait Function1[-T1, +R] extends AnyRef
所以你问的是“如何让Function
的实例也成为C
的子类”。这不是通过标准子类型/继承来实现的,因为很明显我们无法修改Function1
特征来扩展您的自定义类C
。当然,我们可以按照你的建议组成一个新的类来表示函数,但是这只会带我们到目前为止并且实现起来并不容易,更不用说你想用作C
的任何函数了必须首先转换为你的伪功能特征,这会让事情变得可怕。
然而,我们可以做的是创建一个类型类,然后包含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
,但你可以解决问题。