gpt4 book ai didi

scala - 当将 HList 与 GADT 一起使用时,我必须使用 asInstanceOf[H] 进行转换。有没有办法避免 Actor 阵容?

转载 作者:行者123 更新时间:2023-12-02 16:14:43 26 4
gpt4 key购买 nike

鉴于 2 个相互了解的 GADT 代数和 2 个相互递归的解释器,我遇到了必须从类型 A 转换为类型 h <: HList 的问题,即使在模式匹配的上下文中,它应该是隐含的A 型就是 h 型。

有没有办法避免解释器中的 asInstanceOf[h] 调用?

  abstract class KvpHList[H<:HList]
object KvpNil extends KvpHList[HNil]
case class KvpCons[H <: A :: T,A, T<:HList](head: KvpValue[A], tail: KvpHList[T])(implicit isHCons: IsHCons.Aux[H,A,T]) extends KvpHList[H] {
val hCons: IsHCons.Aux[H,A,T] = isHCons
}

abstract class KvpValue[A]
case object StringData extends KvpValue[String]
case class HListData[H <:HList](member: KvpHList[H]) extends KvpValue[H]

def hListInterpreter[H<:HList](hList: KvpHList[H]): H => String = {
hList match {
case KvpNil => (hNil: H) => "Nil"
case cons: KvpCons[H,a,t]=> {
implicit val hCons = cons.hCons
(input: H) => {
s"${kvpInterpreter(cons.head)(input.head)} :: ${hListInterpreter(cons.tail)(input.tail)}"
}
}
}
}

def kvpInterpreter[A](kvpValue: KvpValue[A]): A => String = {
kvpValue match {
case StringData => (str: String) => str
case h: HListData[h] => {
(input: A) => { // tried (input: h) as well
val toString: h => String = hListInterpreter(h.member)
toString(input.asInstanceOf[h]) // <--- CASTING :(
}
}
}
}

kvpInterpreter(HListData(KvpCons(StringData, KvpNil))).apply("Hello" :: HNil)

最佳答案

由于KvpCons中的HAT唯一确定,因此KvpCons > 可以使用两个类型参数而不是三个进行参数化。

类型级模式匹配是类型类

  abstract class KvpHList[H <: HList]
object KvpNil extends KvpHList[HNil]
case class KvpCons[A, T <: HList](head: KvpValue[A], tail: KvpHList[T]) extends KvpHList[A :: T]

abstract class KvpValue[A]
case object StringData extends KvpValue[String]
case class HListData[H <: HList](member: KvpHList[H]) extends KvpValue[H]

trait HListInterpreter[H <: HList] {
def apply(hList: KvpHList[H]): H => String
}

object HListInterpreter {
implicit val nil: HListInterpreter[HNil] = new HListInterpreter[HNil] {
override def apply(hList: KvpHList[HNil]): HNil => String = _ => "Nil"
}

implicit def cons[A, T <: HList](implicit
headKvpInterpreter: KvpInterpreter[A],
tailHListInterpreter: HListInterpreter[T]
): HListInterpreter[A :: T] = new HListInterpreter[A :: T] {
override def apply(hList: KvpHList[A :: T]): A :: T => String = hList match {
case cons: KvpCons[_, _] => input => s"${headKvpInterpreter(cons.head)(input.head)} :: ${tailHListInterpreter(cons.tail)(input.tail)}"
}
}
}

def hListInterpreter[H <: HList](hList: KvpHList[H])(implicit hListInterp: HListInterpreter[H]): H => String = hListInterp(hList)

trait KvpInterpreter[A] {
def apply(kvpValue: KvpValue[A]): A => String
}

object KvpInterpreter {
implicit val string: KvpInterpreter[String] = new KvpInterpreter[String] {
override def apply(kvpValue: KvpValue[String]): String => String = str => str
}

implicit def hList[H <: HList : HListInterpreter]: KvpInterpreter[H] = new KvpInterpreter[H] {
override def apply(kvpValue: KvpValue[H]): H => String = kvpValue match {
case h: HListData[H] => input => {
val toString: H => String = hListInterpreter(h.member)
toString(input)
}
}
}
}

def kvpInterpreter[A](kvpValue: KvpValue[A])(a: A)(implicit kvpInterp: KvpInterpreter[A]): String = kvpInterp(kvpValue)(a)

关于scala - 当将 HList 与 GADT 一起使用时,我必须使用 asInstanceOf[H] 进行转换。有没有办法避免 Actor 阵容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56362440/

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