gpt4 book ai didi

scala - 缺少大小.unapply

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

object Sized (在“shapeless/sized.scala”中)有 unapplySeq ,不幸的是它不提供静态检查。例如,下面的代码将在运行时失败并显示 MatchError :

Sized(1, 2, 3) match { case Sized(x, y) => ":(" }

如果有 unapply 就更好了方法相反,返回元组的选项,元组的具体形状是根据 Sized 实例的大小构造的。例如:
Sized(1) => x
Sized(1, 2) => (x, y)
Sized(1, 2, 3) => (x, y, z)

在这种情况下,前面的代码片段将无法使用 constructor cannot be instantiated to expected type 进行编译.

请帮我实现 unapplyobject Sized .这个方法已经在任何地方实现了吗?

提前致谢!

最佳答案

这绝对是可能的(至少对于 Sized,其中 N 小于 23),但我能想到的唯一方法(禁止宏等)有点困惑。首先,我们需要一个类型类来帮助我们将大小集合转换为 HList s:

import shapeless._, Nat._0
import scala.collection.generic.IsTraversableLike

trait SizedToHList[R, N <: Nat] extends DepFn1[Sized[R, N]] {
type Out <: HList
}

object SizedToHList {
type Aux[R, N <: Nat, Out0 <: HList] = SizedToHList[R, N] { type Out = Out0 }

implicit def emptySized[R]: Aux[R, Nat._0, HNil] = new SizedToHList[R, _0] {
type Out = HNil
def apply(s: Sized[R, _0]) = HNil
}

implicit def otherSized[R, M <: Nat, T <: HList](implicit
sth: Aux[R, M, T],
itl: IsTraversableLike[R]
): Aux[R, Succ[M], itl.A :: T] = new SizedToHList[R, Succ[M]] {
type Out = itl.A :: T
def apply(s: Sized[R, Succ[M]]) = s.head :: sth(s.tail)
}

def apply[R, N <: Nat](implicit sth: SizedToHList[R, N]): Aux[R, N, sth.Out] =
sth

def toHList[R, N <: Nat](s: Sized[R, N])(implicit
sth: SizedToHList[R, N]
): sth.Out = sth(s)
}

然后我们可以定义一个使用这种转换的提取器对象:
import ops.hlist.Tupler

object SafeSized {
def unapply[R, N <: Nat, L <: HList, T <: Product](s: Sized[R, N])(implicit
itl: IsTraversableLike[R],
sth: SizedToHList.Aux[R, N, L],
tupler: Tupler.Aux[L, T]
): Option[T] = Some(sth(s).tupled)
}

进而:
scala> val SafeSized(x, y, z) = Sized(1, 2, 3)
x: Int = 1
y: Int = 2
z: Int = 3

但:
scala> val SafeSized(x, y) = Sized(1, 2, 3)
<console>:18: error: wrong number of arguments for object SafeSized
val SafeSized(x, y) = Sized(1, 2, 3)
^
<console>:18: error: recursive value x$1 needs type
val SafeSized(x, y) = Sized(1, 2, 3)
^

如预期的。

关于scala - 缺少大小.unapply,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23090657/

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