Scala 不合适
在Scala 不合适,scala,shapeless,Scala,Shapeless,在对象大小(在“shapeless/Sized.scala”中)中有unplyseq,不幸的是它不提供静态检查。例如,下面的代码将在运行时失败,出现MatchError: Sized(1, 2, 3) match { case Sized(x, y) => ":(" } 最好使用方法,而不是unapply方法,返回元组选项,并根据大小实例的大小构造元组的具体形状。例如: Sized(1) => x Sized(1, 2) => (x, y) Sized(1, 2, 3) =&
对象大小
(在“shapeless/Sized.scala”中)中有unplyseq
,不幸的是它不提供静态检查。例如,下面的代码将在运行时失败,出现MatchError
:
Sized(1, 2, 3) match { case Sized(x, y) => ":(" }
最好使用方法,而不是unapply
方法,返回元组选项,并根据大小实例的大小构造元组的具体形状。例如:
Sized(1) => x
Sized(1, 2) => (x, y)
Sized(1, 2, 3) => (x, y, z)
在这种情况下,前面的代码段将无法使用编译,构造函数无法实例化为预期的类型
请帮助我为对象大小执行取消应用
。这个方法已经在任何地方实现了吗
提前谢谢 这是绝对可能的(至少对于size
,其中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)
}
但是:
scala>val安全大小(x,y)=大小(1,2,3)
:18:错误:对象SafeSized的参数数目错误
val安全大小(x,y)=大小(1,2,3)
^
:18:错误:递归值x$1需要类型
val安全大小(x,y)=大小(1,2,3)
^
如所愿
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)
^