如何解决通过在 Scala 3 中解包类型将 case 类转换为另一个
enum Container[+A]:
case Value(value: A)
case Default(default: A)
def get: A = this match
case Value(value) => value
case Default(default) => default
case class PersonTemplate(name: Container[String],age: Container[Int],enabled: Container[Boolean])
case class Person(name: String,age: Int,enabled: Boolean)
并且我想在 Scala 3 中编写一个通用函数,将所有 case 类(如 PersonTemplate
)转换为对应的 Person
,例如:
def extract[I <: Product,O <: Product](input: I): O = ???
val initial = PersonTemplate(Value("John"),Default(12),Default(true))
val final = extract[PersonTemplate,Person](initial)
// Result: Person("John",12,true)
我尝试了几种方法,但都没有成功,主要是因为我不明白如何使用 Scala 3 Tuple
,它在我看来与 Scala 2 Shapeless' HList
(甚至在无形的我没那么好)。
我的总体方法是:
- 将 case 类转换为元组。为此,我找到了
Tuple.fromProductTyped
- 将每个元素限制为
Container[_]
。我发现Tuple.IsMappedBy
可以保证元组具有正确的形状,而Tuple.InverseMap
似乎可以提取容器内的类型。不过,我不确定把这段代码放在哪里。 - 对每个调用
Container.get
的值应用(poly?)函数。我在网上找到的那个小东西最后用了很多.asInstanceOf
,但对我来说似乎不太合适。 - 使用
Tuple
将结果summon[Mirror.Of[O]].fromProduct(output)
转换为输出类型
def resolve[I <: Product: Mirror.ProductOf,O: Mirror.ProductOf](input: I): O =
val processed =
Tuple
.fromProductTyped(input)
.map { [T] => (value: T) => ??? }
summon[Mirror.Of[O]].fromProduct(processed)
type ExtractG = [G] =>> G match {
case Container[a] => a
}
def process[I <: Tuple,O <: Tuple](input: I)(using Tuple.IsMappedBy[Container][I]): O =
input.map { [A] => (a: A) =>
a.asInstanceOf[Container[_]].get.asInstanceOf[ExtractG[A]]
}.asInstanceOf[O]
解决方法
好吧,如果你不介意一些铸造,你可以这样做:
def unwrapper[From <: Product,To](
using To: Mirror.ProductOf[To],From: Mirror.ProductOf[From],ev: From.MirroredElemTypes =:= Tuple.Map[To.MirroredElemTypes,Container]
): (From => To) =
from => To.fromProduct {
from.productIterator
.toArray
.map(_.asInstanceOf[Container[_]].get)
.foldRight[Tuple](EmptyTuple)(_ *: _)
}
@main def run =
import Container._
val unTemplate = unwrapper[PersonTemplate,Person]
println(unTemplate(PersonTemplate(Value("foo"),Default(42),Default(false))))
请求的 From
和 ev
仅用于证明所有类型转换的类型安全。 IMO 镜像机器缺乏以类型安全的方式操作事物的能力,而没有像 shapeless can 这样的宏。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。