Scala 避免在返回值中丢失类型信息
我试图找到一种方法来避免在方法的返回值中丢失类型信息 我有以下资料:Scala 避免在返回值中丢失类型信息,scala,implicit,shapeless,hlist,Scala,Implicit,Shapeless,Hlist,我试图找到一种方法来避免在方法的返回值中丢失类型信息 我有以下资料: val defs0 = Default.mkDefault[Person, Some[String] :: Some[Int] :: HNil](Some("odd") :: Some(42) :: HNil) 使用IntelliJs“添加类型注释”可提供以下类型: Default.Aux[Person, ::[Some[String], ::[Some[Int], HNil]]] 这很好,只是我不想在调用mkDefaul
val defs0 = Default.mkDefault[Person, Some[String] :: Some[Int] :: HNil](Some("odd") :: Some(42) :: HNil)
使用IntelliJs“添加类型注释”可提供以下类型:
Default.Aux[Person, ::[Some[String], ::[Some[Int], HNil]]]
这很好,只是我不想在调用mkDefault时指定Person的字段。所以我创造了这个:
object MkDefault {
object toSome extends Poly1 {
implicit def default[P] = at[P](Some(_))
}
def apply[P, L <: HList, D <: HList]
(p: P)
(implicit
lg: LabelledGeneric.Aux[P, L],
mpr: Mapper.Aux[toSome.type, L, D]
): Default.Aux[P, D] =
Default.mkDefault[P, D](mpr(lg.to(p)))
}
这很好,但IntellJ中的推断类型如下所示:
Default.Aux[Person, HNil]
如何使defs1的推断类型等于defs0的推断类型?
*在不必指定类Person的字段的情况下,使用
mpr.Out
而不是D
作为输出类型:
object MkDefault {
object toSome extends Poly1 {
implicit def default[P] = at[P](Some(_))
}
def apply[P, L <: HList, D <: HList]
(p: P)
(implicit
lg: LabelledGeneric.Aux[P, L],
mpr: Mapper.Aux[toSome.type, L, D]
): Default.Aux[P, mpr.Out] =
Default.mkDefault[P, D](mpr(lg.to(p)))
}
附言
如果您不介意使用选项
而不是某些
,也可以使用a选项
val opt = Default.AsOptions[Person]
val def3 = Default.mkDefault[Person, opt.Out](Some("aaa") :: Some(5) :: HNil)
检查:
scala> implicitly[def3.Out =:= ::[Option[String], ::[Option[Int], HNil]]]
res12: =:=[def3.Out,shapeless.::[Option[String],shapeless.::[Option[Int],shapeless.HNil]]] = <function1>
scala>隐式[def3.Out=::::[Option[String],::[Option[Int],HNil]]
res12:=:=[def3.Out,无形状:[选项[String],无形状:[选项[Int],无形状.HNil]]=
使用mpr.Out
作为输出类型,而不是D
太棒了,谢谢!然而,为了得到完全相同的类型,我需要使用泛型而不是LabelledGeneric。如果没有你的回答,你是不会发现的,所以标记为已接受:)
val opt = Default.AsOptions[Person]
val def3 = Default.mkDefault[Person, opt.Out](Some("aaa") :: Some(5) :: HNil)
scala> implicitly[def3.Out =:= ::[Option[String], ::[Option[Int], HNil]]]
res12: =:=[def3.Out,shapeless.::[Option[String],shapeless.::[Option[Int],shapeless.HNil]]] = <function1>