gpt4 book ai didi

Scala 构造函数抽象

转载 作者:行者123 更新时间:2023-12-04 09:27:19 25 4
gpt4 key购买 nike

在 Scala 中可以执行以下操作:

scala> val l = List
l: scala.collection.immutable.List.type = scala.collection.immutable.List$@7960c21a

scala> l ( 1, 2, 3 )
res0: List[Int] = List(1, 2, 3)

换句话说,Scala 具有高阶多态性。我想使用高阶多态性来做以下事情。
sealed abstract class A { def eval () : A }
case class A0 () extends A { ... }
case class A1 ( a : A ) extends A { ... }
case class A2 ( a : A, b : A ) extends A { ... }
....

所以我有一堆案例类, A的子类,其构造函数不一定采用相同数量的参数。我还想要一个“通用”案例类,如下所示:
case class ApplyA ( c : ???, l : List [ A ] ) extends A {
def eval () : A = { ??? } }

这个想法是 ApplyAA 的子类型的构造函数作为第一个参数,以及参数列表。 eval如果可能,方法然后使用构造函数构造一个适当的类(即列表具有正确的长度)并返回它
(这对应于上述 l ( 1, 2, 3) 示例中的 List)。 ApplyA 的第一个构造函数的参数类型是什么? ?

这应该可以通过高阶多态性实现,但我不知道怎么做。我知道即使不使用高阶多态,我也可以做到这一点,只需将构造函数包装在函数中,然后将这些函数作为第一个参数传递给 ApplyA 的构造函数。 ,但我想了解如何直接使用高阶多态性。

最佳答案

@alexey_r 说得对,您的 List示例不涉及高阶多态性。但是,如果您准备使用一些 type-level heavy artillery你可以抽象你的 A{0,1,2}构造函数来获得看起来非常接近你所要求的东西。

首先要注意的是,正如所写的,你的“通用”类不可能被实现,

case class ApplyA(c : ???, l : List[A]) ...

因为在构造函数的数量之间没有编译时可检查的关系 c和列表的长度 l .我们可以通过更换 List 来解决这个问题。与 HList并帮助我们从具有任意元数的普通函数转换为具有单个 HList 的函数争论,
import shapeless.HList._
import shapeless.Functions._

sealed abstract class A { def eval() : A }
case class A0 () extends A { def eval() = this }
case class A1 ( a : A ) extends A { def eval() = this }
case class A2 ( a : A, b : A ) extends A { def eval() = this }

case class ApplyA[C, L <: HList, HF](c : C, l : L)
(implicit hl : FnHListerAux[C, HF], ev : HF <:< (L => A)) extends A {
def eval () : A = hl(c)(l)
}

val a : A = A0()

val a0 = ApplyA(A0.apply _, HNil)
val a1 = ApplyA(A1.apply _, a :: HNil)
val a2 = ApplyA(A2.apply _, a :: a :: HNil)

隐式参数 hl : FnHListerAux[C, HF]提供从构造函数的转换,无论它是什么,从单个 HList 参数到函数。和隐式参数 ev : HF <:< (L => A)见证提供的长度 HList of 构造函数参数的长度正确(和类型 FWIW,但这在本例中几乎不相关)。

关于Scala 构造函数抽象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8270526/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com