gpt4 book ai didi

scala - HList的约束: check for single occurrence of a type

转载 作者:行者123 更新时间:2023-12-04 07:18:41 25 4
gpt4 key购买 nike

我试图在HList上添加一个约束(来自Shapeless):

  • ,它应该包含任意数量的TA类型的元素(从0到N);
  • 它应仅包含一个类型为TB的元素。

  • 我的示例具有以下类型层次结构:
    trait T
    case class TA extends T
    case class TB extends T

    举个例子:
  • tb :: HNil是有效的
  • ta :: tb ::HNil是有效的
  • ta :: tb :: ta :: HNil是有效的
  • ta :: HNil无效
  • HNil无效

  • 我无法弄清楚如何将其表达为约束。

    最佳答案

    您可以使用一个自定义类型类来做到这一点,该类见证了一个TB的存在,而其他所有元素都是TA的。如果您想以归纳方式建立此列表,则会看到有两种情况需要处理-到目前为止您所看到的一切都是TA(我们可以用ToList[T, TA]看到),而当前元素是TB,或者您已经看到了一个TB,而当前元素是一个TA:

    import shapeless._, ops.hlist.{ ToList }

    trait T
    case class TA() extends T
    case class TB() extends T

    trait UniqueTB[L <: HList] extends DepFn1[L] {
    type Out = TB
    def apply(l: L): TB
    }

    object UniqueTB {
    def apply[L <: HList](implicit utb: UniqueTB[L]): UniqueTB[L] = utb
    def getTB[L <: HList](l: L)(implicit utb: UniqueTB[L]): TB = utb(l)

    implicit def firstTB[T <: HList](
    implicit tl: ToList[T, TA]
    ): UniqueTB[TB :: T] = new UniqueTB[TB :: T] {
    def apply(l: TB :: T): TB = l.head
    }

    implicit def afterTB[T <: HList](
    implicit utb: UniqueTB[T]
    ): UniqueTB[TA :: T] = new UniqueTB[TA :: T] {
    def apply(l: TA :: T): TB = utb(l.tail)
    }
    }

    然后:
    scala> UniqueTB[TB :: HNil]
    res0: UniqueTB[shapeless.::[TB,shapeless.HNil]] = UniqueTB$$anon$1@385c6929

    scala> UniqueTB[TA :: TB :: HNil]
    res1: UniqueTB[shapeless.::[TA,shapeless.::[TB,shapeless.HNil]]] = UniqueTB$$anon$2@682dd97e

    scala> UniqueTB[TA :: TB :: TA :: HNil]
    res2: UniqueTB[shapeless.::[TA,shapeless.::[TB,shapeless.::[TA,shapeless.HNil]]]] = UniqueTB$$anon$2@5ef48f82

    scala> UniqueTB[TB :: HNil]
    res3: UniqueTB[shapeless.::[TB,shapeless.HNil]] = UniqueTB$$anon$1@33be241

    scala> UniqueTB[TA :: HNil]
    <console>:25: error: could not find implicit value for parameter utb: UniqueTB[shapeless.::[TA,shapeless.HNil]]
    UniqueTB[TA :: HNil]
    ^

    scala> UniqueTB[HNil]
    <console>:25: error: could not find implicit value for parameter utb: UniqueTB[shapeless.HNil]
    UniqueTB[HNil]
    ^

    scala> UniqueTB[TB :: TB :: HNil]
    <console>:25: error: could not find implicit value for parameter utb: UniqueTB[shapeless.::[TB,shapeless.::[TB,shapeless.HNil]]]
    UniqueTB[TB :: TB :: HNil]
    ^

    我给类型类提供了一个返回 TB的操作,但是如果不需要的话,可以将其保留为无方法。

    关于scala - HList的约束: check for single occurrence of a type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39226147/

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