问题描述
鉴于以下内容
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
我怎样才能得到以下内容?
How can I get the following ?
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 失败
but fail for 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.::[Option[B],shapeless.HNil]]]]]
推荐答案
很可能你唯一能做的就是为 Some
和 None
定义单独的案例:
Most likely the only thing you can do is define separate cases for Some
and for 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)
}
这也意味着你不能在类型中使用泛型Option
,它必须在编译时知道每个元素是否是Some
或 无
:
It also means you can't use generic Option
s in the types, it must be known at compile time whether each element is Some
or None
:
scala> (Some(A(1)) :: A(2) :: Some(B("two")) :: None :: HNil) flatMap f
res1: shapeless.::[A,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
类型.
This distinction defines the type of the resulting expression: Some(1) :: HNil flatMap f
will have type ::[Int, HNil]
, but None :: HNil flatMap f
will have type just HNil
.
这种类型信息在编译时无法从简单的Option
s: should (x: Option[T]) :: HNil flatMap f
有类型 ::[T, HNil]
或 HNil
?直到我们实际运行程序并查看 x
的值时,我们才知道.
This kind of type information can't be figured out at compile time from simple Option
s: should (x: Option[T]) :: HNil flatMap f
have type ::[T, HNil]
or HNil
? We don't know until we actually run the program and see what the value of x
is.
我不确定是否有一些聪明的方法可以做到这一点并获得不透明的 HList
,但是此时您将放弃有关每个元素和列表长度的确切类型信息也可以将其转换为普通的 List
(如果您知道最终结果的确切类型,也可以稍后使用 cast
from shapeless)
I'm not sure if there's some smart way to do it anyway and get an opaque HList
, but at that point you'll abandon exact type information about each element and the length of the list and may as well cast it to a normal List
(and maybe use cast
from shapeless later if you know what exact type the final result will have)
这篇关于带有选项的无形状平面图 HList 产生 HList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!