无形:将元组映射到选项的一些选项

DAN*_*Fan 6 scala shapeless

(Some(1), 2, Some(3))
Run Code Online (Sandbox Code Playgroud)

我希望得到

(Some(1), Some(2), Some(3))
Run Code Online (Sandbox Code Playgroud)

没有形状是否可以这样做?

Mil*_*bin 7

是的,

scala> import shapeless._, syntax.std.tuple._
import shapeless._
import syntax.std.tuple._

scala> :paste
// Entering paste mode (ctrl-D to finish)

object opt extends opt0 {
  implicit def optId[T <: Option[_]] = at[T](identity)
}
trait opt0 extends Poly1 {
  implicit def default[T] = at[T](Option(_))
}

// Exiting paste mode, now interpreting.

defined object opt
defined trait opt0

scala> (Some(1), 2, Some(3)) map opt
res0: (Some[Int], Option[Int], Some[Int]) = (Some(1),Some(2),Some(3))
Run Code Online (Sandbox Code Playgroud)

你会注意到Some[Int]第一个和最后一个位置的位置已被保留,而提升的中间元素被输入为Option[Int].我已经假设你实际想要的是这样的,

scala> (Option(1), 2, Option(3)) map opt
res1: (Option[Int], Option[Int], Option[Int]) = (Some(1),Some(2),Some(3))
Run Code Online (Sandbox Code Playgroud)


Mat*_*zyk 6

没有形状可以做很多!

  import shapeless._
  import syntax.std.tuple._

  trait basicOption extends Poly1 {
    implicit def default[T] = at[T](t => Some(t))
  }

  object fullOption extends basicOption {
    implicit def caseSome[T] = at[Some[T]](s => s)
    implicit def caseNone = at[None.type](s => s)
  }

  println((Some(1),2,Some(3)).map(fullOption)) // (Some(1),Some(2),Some(3))
  println((Some(1),2,None).map(fullOption)) // (Some(1), Some(2), None)
Run Code Online (Sandbox Code Playgroud)

有关更多示例,您可以查看他们的github仓库

这适用于Shapeless 2.0及以上版本,如果你使用较旧的东西,你仍然可以做到,但不是map直接调用元组你必须经历一个HList.