如何解决用于元组的 Scala 3 类型绑定`<:<` 技巧
在线会议期间,Adam Warski 展示了一个技巧来证明元组具有特定结构:
第一个实现是
def sequence[T <: Tuple](t: T): Option[InverseMap[T,Option]] =
val unwrapped = t.productIterator.collect { case Some(v) => v}.toArray[Any]
if unwrapped.length == t.productArity then Some(Tuple.fromArray(unwrapped).asInstanceOf[InverseMap[T,Option]])
else None
允许(但不应该)
sequence(("x",true)) // compiles
并用技巧实现
def betterSequence[T <: Tuple](t: T)(using T <:< Map[InverseMap[T,Option],Option]): Option[InverseMap[T,Option]] =
val unwrapped = t.productIterator.collect { case Some(v) => v}.toArray[Any]
if unwrapped.length == t.productArity then Some(Tuple.fromArray(unwrapped).asInstanceOf[InverseMap[T,Option]])
else None
betterSequence(("x",true)) // compile error
能解释一下吗
(using T <:< Map[InverseMap[T,Option])
有效以及为什么 T
是 Map
的子类型?
解决方法
InverseMap[T,Foo]
接受一个看起来像 T
的元组 (Foo[t1],Foo[t2],...,Foo[tn])
并将它变成一个元组 (t1,t2,tn)
。如果 T
没有那个结构,即它不是一堆 Foo
,它不会编译(有一个有点神秘的错误)。这是证明元组中只有 Option
的主要因素。
下一个问题是如何将这个类型插入到 betterSequence
方法中。 Map[T,Foo]
将看起来像 T
的元组 (t1,tn)
变成 (Foo[t1],Foo[tn])
(InverseMap
的倒数)。因此,Map[InverseMap[T,Option],Option]
只是 T
(想想数学,其中 f(f^-1(x)) 又是 x。边界 T <:< T
将始终为真,但前提是InverseMap
先成功。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。