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

scala – 带有选项的无形平面图HList产生HList

发布时间:2020-12-16 08:44:19 所属栏目:安全 来源:网络整理
导读:鉴于以下内容 case class A(value:Int)case class B(value:String)val h:Option[A] :: A :: Option[B] :: Option[A] :: HNil = Some(A(1)) :: A(2) :: Some(B("two")) :: (None:Option[B]) :: HNil 我怎样才能得到以下内容? A(1) :: A(2) :: B("two") :: HN
鉴于以下内容

case class A(value:Int)
case class B(value:String)

val h:Option[A] :: A :: Option[B] :: Option[A] :: HNil = Some(A(1)) :: A(2) :: Some(B("two")) :: (None:Option[B]) :: HNil

我怎样才能得到以下内容?

A(1) :: A(2) :: B("two") :: HNil

我的尝试如下

trait a extends Poly1 {
    implicit def any[T] = at[T](_ :: HNil)
}
object f extends a {            
    implicit def some[T] = at[Option[T]](t => if (t.isDefined) t.get :: HNil else HNil)         
}

适用于地图

h map f

> A(1) :: HNil :: A(2) :: HNil :: B(two) :: HNil :: HNil :: HNil

但是flatMap失败了

h flatMap f

> could not find implicit value for parameter mapper: shapeless.ops.hlist.FlatMapper[f.type,shapeless.::[Option[A],shapeless.::[A,shapeless.::[Option[B],shapeless.HNil]]]]]

解决方法

很可能你唯一能做的就是为Some和None定义单独的案例:

trait a extends Poly1 {
  implicit def default[T] = at[T](_ :: HNil)
}
object f extends a {
  implicit def caseSome[T] = at[Some[T]](_.get :: HNil)
  implicit def caseNone = at[None.type](_ => HNil)
}

它还意味着您不能在类型中使用泛型选项,在编译时必须知道每个元素是Some还是None:

scala> (Some(A(1)) :: A(2) :: Some(B("two")) :: None :: HNil) flatMap f
res1: shapeless.::[A,shapeless.::[B,shapeless.HNil]]] = A(1) :: A(2) :: B(two) :: HNil

这种区别定义了结果表达式的类型:Some(1):: HNil flatMap f的类型为:: [Int,HNil],但None :: HNil flatMap f的类型只是HNil.

在编译时无法从简单的选项中找出这种类型的信息:should(x:Option [T]):: HNil flatMap f有类型:: [T,HNil]还是HNil?直到我们实际运行程序并看到x的值是什么,我们才知道.

我不确定是否有一些聪明的方法可以做到这一点并获得一个不透明的HList,但在那时你将放弃关于每个元素的精确类型信息和列表的长度,并且可以将其转换为正常的列表(如果你知道最终结果会有什么样的确切类型,也可以在以后使用无形投射)

(编辑:李大同)

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

    推荐文章
      热点阅读