加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 固定大小和元素界限的列表

发布时间:2020-12-16 08:45:30 所属栏目:安全 来源:网络整理
导读:使用无形,我正在尝试定义一个函数: import shapeless._import ops.nat._import nat._def threeNatsLessThan3[N : Nat](xs: Sized[List[N],N]) (implicit ev: LTEq[N,_3]) = ??? 只有当输入xs是Nat的List(大小为3)时,它才会编译,其中每个元素都是 = 3. 但是
使用无形,我正在尝试定义一个函数:

import shapeless._
import ops.nat._
import nat._

def threeNatsLessThan3[N <: Nat](xs: Sized[List[N],N])
   (implicit ev: LTEq[N,_3]) = ???

只有当输入xs是Nat的List(大小为3)时,它才会编译,其中每个元素都是< = 3. 但是无法编译:

scala> threeNatsLessThan3[_3](List(_1,_2,_3))
<console>:22: error: type mismatch;
 found   : List[shapeless.Succ[_ >: shapeless.Succ[shapeless.Succ[shapeless._0]] with shapeless.Succ[shapeless._0] with shapeless._0 <: Serializable with shapeless.Nat]]
 required: shapeless.Sized[List[shapeless.nat._3],shapeless.nat._3]
    (which expands to)  shapeless.Sized[List[shapeless.Succ[shapeless.Succ[shapeless.Succ[shapeless._0]]]],shapeless.Succ[shapeless.Succ[shapeless.Succ[shapeless._0]]]]a>
       twoNatsFirstLtEqSecond[_3](List(_1,_3))
                                      ^

如何正确实现上述功能?

此外,我也很欣赏使用HList的解决方案,其中HList仅包含Nat元素(如果可能).

解决方法

您输入的签名是大小为N的列表,其中仅包含N类型的元素.对于whit,Sized [List [N],N]表示以下之一:List(_1),List(_2,_2) ),或最后列出(_3,_3,_3),考虑到你的类型级别约束.这几乎就是你想要的,并解释了编译器给你的错误:

required: shapeless.Sized[List[shapeless.nat._3],shapeless.nat._3]

要开始分解您想要完成的任务,我们需要注意您不能拥有List [Nat]并保留各个类型. Nat的抽象性会使他们模糊不清.因此,如果你想在编译时做一些事情,你将有三个选择:使用HList,选择在列表中修复Nat的类型,以便你有List [N]或选择修复大小列表[Nat]与大小.

如果你想说List的大小小于3,那么

def lessThanThree[N <: Nat](sz: Sized[List[Nat],N])(implicit ev: LTEq[N,_3]) = sz

如果你想说List的Nat小于3,那么List中的N也是固定的:

def lessThanThree[N <: Nat,M <: Nat](sz: Sized[List[N],M])(implicit ev: LTEq[N,_3]) = sz

如果您正在寻找可能使用Poly,您可以为任何Nat定义一个at以保留LTEq约束,您需要了解Sized确实使得地图符合更接近于上面的标准包映射大多数集合,即它需要CanBuildFrom.结合列表中的个体Nat的擦除意味着您将遇到很多困难,提出一种解决方案,为您提供所需的灵活性.

如果您使用HList,则可以执行以下操作:

object LT3Identity extends Poly{
   implicit def only[N <: Nat](implicit ev: LTEq[N,_3]) = at[N]{ i => i}
 }

 def lt3[L <: HList,M <: Nat](ls: L)(implicit lg: Length.Aux[L,M],lt: LTEq[M,_3]) = ls.map(LT3Identity)

这样做既可以将Hlist的大小限制为小于3,同时也只允许包含小于或等于3的Nat的HList.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读