This does not compile and I do not understand why:
import shapeless._
import poly._
object option extends (Option ~> List) {
def apply[T](t: Option[T]) = t.toList
}
val simple = Some(1) :: Some("hello") :: Some(true) :: HNil
val opts: List[Int] :: List[String] :: List[Boolean] :: HNil = simple map option
This is somewhat surprising, because this does compile:
import shapeless._
import poly._
object choose extends (Set ~> Option) {
def apply[T](s: Set[T]) = s.headOption
}
val sets = Set(1) :: Set("foo") :: HNil
val opts: Option[Int] :: Option[String] :: HNil = sets map choose
The problem is your usage of Some
instead of Option
. The compiler complains that it can't find anything to convert a list of Some
s though your Option
mapper is being used. To fix this you can:
Change your simple list construction to use Option
instead of Some
:
object option extends (Option ~> List) {
def apply[T](t: Option[T]) = t.toList
}
val simple = Option(1) :: Option("hello") :: Option(true) :: HNil
val opts2: List[Int] :: List[String] :: List[Boolean] :: HNil = simple map option
Use Some
as the type of your mapper:
object option extends (Some ~> List) {
def apply[T](t: Some[T]) = t.toList
}
val simple = Some(1) :: Some("hello") :: Some(true) :: HNil
val opts2: List[Int] :: List[String] :: List[Boolean] :: HNil = simple map option
Or force the type of simple to be downcast to Option
:
object option extends (Option ~> List) {
def apply[T](t: Option[T]) = t.toList
}
val simple: Option[Int] :: Option[String] :: Option[Boolean] :: HNil = Some(1) :: Some("hello") :: Some(true) :: HNil
val opts2: List[Int] :: List[String] :: List[Boolean] :: HNil = simple map option
来源:https://stackoverflow.com/questions/26127542/why-does-mapping-over-an-hlist-of-optiont-not-work