微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Scala 3 中提取元组的子集

如何解决在 Scala 3 中提取元组的子集

给定一个任意元组,我想提取元组一个子集。 签名看起来像:

def subset[T1 <: Tuple,T2 <: Tuple](t:T1): T2 = ???

其中 T2一个元组,其中包含从 T1 中选择的一些成员子集。

使用它看起来像

subset[(String,Int,Boolean),(String,Boolean)]( ("str",42,true) ) == ("str",true)

我知道这需要大量使用匹配类型和类型级编程。我觉得 Shapeless 非常简单,但我在元组 vs HLIST 上缺少 std lib 中的一些功能

解决方法

这看起来像是类型类的工作! (请注意,唯一需要的 Scala 3 特定功能是 *:

def subset[T1 <: Tuple,T2 <: Tuple](t: T1)(using s: Subset[T1,T2]): T2 = s(t)

opaque type Subset[T1 <: Tuple,T2 <: Tuple] = T1 => T2
object Subset:
  given [T1 <: Tuple]: Subset[T1,EmptyTuple] = _ => EmptyTuple
  given [A,T1 <: Tuple,T2 <: Tuple](using s: Subset[T1,T2]): Subset[A *: T1,A *: T2] =
    case a *: t => a *: s(t)
  given [A,T2] =
    case _ *: t => s(t)

See it in Scastie

如果您希望它不分顺序地工作,它会稍微复杂一些,但仍然易于管理:

opaque type Find[T <: Tuple,E] = T => E
object Find:
  given [T <: Tuple]: Find[T,T <: Tuple]: Find[A *: T,A] = 
    case a *: _ => a
  given [A,H,T <: Tuple](using f: Find[T,A]): Find[H *: T,A] =
    case _ *: t => f(t)

opaque type Subset[T1 <: Tuple,T2 <: Tuple](using 
      s: Subset[T1,T2],f: Find[T1,A]
  ): Subset[T1,A *: T2] =
    t => f(t) *: s(t)

def subset[T1 <: Tuple,T2]): T2 = s(t)

See it in Scastie

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。