Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 将列表转换为案例类_Scala_Shapeless - Fatal编程技术网

Scala 将列表转换为案例类

Scala 将列表转换为案例类,scala,shapeless,Scala,Shapeless,作为练习,我试图看看是否可以使用shapeless将列表(任何)转换为case类 我试图实现的一个非常基本的例子: case class Foo(i: Int, j: String) val foo: Option[Foo] = fromListToCaseClass[Foo]( List(1:Any, "hi":Any) ) 以下是我如何制定我的解决方案,这可能会非常困难: def fromListToCaseClass[CC <: Product](a: List[Any]): O

作为练习,我试图看看是否可以使用shapeless将列表(任何)转换为case类

我试图实现的一个非常基本的例子:

case class Foo(i: Int, j: String)
val foo: Option[Foo] = fromListToCaseClass[Foo]( List(1:Any, "hi":Any) ) 
以下是我如何制定我的解决方案,这可能会非常困难:

def fromListToCaseClass[CC <: Product](a: List[Any]): Option[CC] = a.toHList[???].map( x => Generic[CC].from(x) )

我想知道这是否有意义,或者我离这里很远。我们能做到这一点吗?还有其他建议吗?谢谢

您可以通过以下方式使用“无形状”完成此操作:

import shapeless._

trait Creator[A] { def apply(list:List[Any]): Option[A] }

object Creator {
  def as[A](list: List[Any])(implicit c: Creator[A]): Option[A] = c(list)

  def instance[A](parse: List[Any] => Option[A]): Creator[A] = new Creator[A] {
    def apply(list:List[Any]): Option[A] = parse(list)
  }

  def arbitraryCreate[A] = instance(list => list.headOption.map(_.asInstanceOf[A]))

  implicit val stringCreate = arbitraryCreate[String]
  implicit val intCreate = arbitraryCreate[Int]
  implicit val hnilCreate = instance(s => if (s.isEmpty) Some(HNil) else None)

  implicit def hconsCreate[H: Creator, T <: HList: Creator]: Creator[H :: T] =
instance {
  case Nil => None
  case list => for {
    h <- as[H](list)
    t <- as[T](list.tail)
  } yield h :: t
}

implicit def caseClassCreate[C, R <: HList](
  implicit gen: Generic.Aux[C, R], 
  rc: Creator[R]): Creator[C] = 
    instance(s => rc(s).map(gen.from))
}

您可以通过以下方式使用“无形状”完成此操作:

import shapeless._

trait Creator[A] { def apply(list:List[Any]): Option[A] }

object Creator {
  def as[A](list: List[Any])(implicit c: Creator[A]): Option[A] = c(list)

  def instance[A](parse: List[Any] => Option[A]): Creator[A] = new Creator[A] {
    def apply(list:List[Any]): Option[A] = parse(list)
  }

  def arbitraryCreate[A] = instance(list => list.headOption.map(_.asInstanceOf[A]))

  implicit val stringCreate = arbitraryCreate[String]
  implicit val intCreate = arbitraryCreate[Int]
  implicit val hnilCreate = instance(s => if (s.isEmpty) Some(HNil) else None)

  implicit def hconsCreate[H: Creator, T <: HList: Creator]: Creator[H :: T] =
instance {
  case Nil => None
  case list => for {
    h <- as[H](list)
    t <- as[T](list.tail)
  } yield h :: t
}

implicit def caseClassCreate[C, R <: HList](
  implicit gen: Generic.Aux[C, R], 
  rc: Creator[R]): Creator[C] = 
    instance(s => rc(s).map(gen.from))
}

这可以直接使用shapeless的泛型和FromTraversable类型类来完成

import scala.collection.GenTraversable
import shapeless._, ops.traversable.FromTraversable

class FromListToCaseClass[T] {
  def apply[R <: HList](l: GenTraversable[_])
    (implicit gen: Generic.Aux[T, R], tl: FromTraversable[R]): Option[T] =
      tl(l).map(gen.from)
}
def fromListToCaseClass[T] = new FromListToCaseClass[T]

这可以直接使用shapeless的泛型和FromTraversable类型类来完成

import scala.collection.GenTraversable
import shapeless._, ops.traversable.FromTraversable

class FromListToCaseClass[T] {
  def apply[R <: HList](l: GenTraversable[_])
    (implicit gen: Generic.Aux[T, R], tl: FromTraversable[R]): Option[T] =
      tl(l).map(gen.from)
}
def fromListToCaseClass[T] = new FromListToCaseClass[T]

很好的尝试,但您缺少Typeable和FromTraversable,它们处理您试图与Creator解决的问题。很好的尝试,但您缺少Typeable和FromTraversable,它们处理您试图与Creator解决的问题。
scala> case class Foo(i: Int, j: String)
defined class Foo

scala> fromListToCaseClass[Foo](List(23, "foo"))
res0: Option[Foo] = Some(Foo(23,foo))

scala> fromListToCaseClass[Foo](List(23, false))
res1: Option[Foo] = None