如何在 Scala 中扩展函数 N 类



我是Scala的新手。 我有一个Class AextendsClass C.我还有一个Class B,也extendsClass C

我希望A->B类型的函数对象也扩展C(以及其他派生类型,例如A->(A->B))。但我在"Programming in scala"中读到:

函数文本被编译成一个类,当在运行时实例化时 是一个函数值。

有没有办法自动让A->BextendC,而不是手动创建一个代表函数的新类?

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 的值。

使用typeclass,您可以实现相同的目标,但具有一些额外的优势,例如,有一天可以在不更改现有代码的情况下将D添加到系列中(您只需要在范围内的某个地方实现类型C[D]的隐式值)。

因此,它不是someMethodC的实例,而是简单地采用某种类型(我们称之为s)的东西(我们称之为Something),并具有C[Something]必须存在的约束。如果您传递了不存在 C 实例的内容,您将收到一个错误:

trait NotC
someMethod(new NotC {}) 
// Error: could not find implicit value for evidence parameter of type C[NotC]

你实现了同样的事情 - 你有一个C家庭,其成员是ABA => B,但你绕过子类型问题。

最新更新