具有案例类参数的案例类的不一致含义

时间:2016-07-31 01:05:06

标签: scala shapeless

鉴于以下特拉维斯·布朗的教育和写得很好的Type classes and generic derivation

case class Person(name: String, age: Double)

 trait Parser[A] {
    def apply(s: String): Option[A]
  }

  implicit val hnilParser: Parser[HNil] = new Parser[HNil] {
    def apply(s: String): Option[HNil] = if(s.isEmpty) Some(HNil) else None
  }

  implicit def hconsParser[H: Parser, T <: HList: Parser]: Parser[H :: T] = new Parser[H :: T] {
    def apply(s: String): Option[H :: T] = s.split(",").toList match {
      case cell +: rest => for {
        head <- implicitly[Parser[H]].apply(cell)
        tail <- implicitly[Parser[T]].apply(rest.mkString(","))
      } yield head :: tail
    }
  }

  implicit val stringParser: Parser[String] = new Parser[String] {
    def apply(s: String): Option[String] = Some(s)
  }

  implicit val intParser: Parser[Int] = new Parser[Int] {
    def apply(s: String): Option[Int] = Try(s.toInt).toOption
  }

  implicit val doubleParser: Parser[Double] = new Parser[Double] {
    def apply(s: String): Option[Double] = Try(s.toDouble).toOption
  }

  implicit val booleanParser: Parser[Boolean] = new Parser[Boolean] {
    def apply(s: String): Option[Boolean] = Try(s.toBoolean).toOption
  }

  implicit def caseClassParser[A, R <: HList](implicit gen: Generic[A] { type Repr = R },
                                              reprParser: Parser[R]): Parser[A] =
    new Parser[A] {
      def apply(s: String): Option[A] = reprParser.apply(s).map(gen.from)
    }


  object Parser {
    def apply[A](s: String)(implicit parser: Parser[A]): Option[A] = parser(s)
  }

  implicit val stringParser: Parser[String] = new Parser[String] {
    def apply(s: String): Option[String] = Some(s)
  }

  implicit val intParser: Parser[Int] = new Parser[Int] {
    def apply(s: String): Option[Int] = Try(s.toInt).toOption
  }

  implicit val doubleParser: Parser[Double] = new Parser[Double] {
    def apply(s: String): Option[Double] = Try(s.toDouble).toOption
  }

我很想尝试获得一个Parser[X],其中X是一个带有Person参数的案例类,即一个案例类:

case class PersonWrapper(person: Person, x: Int)

然而我收到了一个错误:

scala> Parser[PersonWrapper]("kevin,66,42")
<console>:15: error: diverging implicit expansion for type net.Test.Parser[net.Test.PersonWrapper]
starting with method caseClassParser in object Test
       Parser[PersonWrapper]("kevin,66,42")
                            ^

首先,为什么会出现这种不同的隐式错误?

其次,是否可以使用上述代码获取Parser[PersonWrapper]

1 个答案:

答案 0 :(得分:1)

  

其次,是否可以使用上面的代码来获取Parser [PersonWrapper]?

不,只是跳到文章末尾:

[MemberPattern("Given User (.*) should login")]
public bool LoginUser(string user) { ... }

[MemberPattern("When Placing (.*) Order")]
public bool PlacingOrder(string side) { ... }

[MemberPattern("Then Order Available In Market")]
public bool OrderAvailableInMarket() { ... }
     

我们的格式不支持任何类型的嵌套(至少我们没有说过任何关于嵌套的内容,并且它不会是微不足道的),因此我们实际上并不知道如何将字符串解析为BookBook。 ..

问题是scala> case class BookBook(b1: Book, b2: Book) defined class BookBook scala> Parser[BookBook]("Hamlet,Shakespeare") res7: Option[BookBook] = None 中的cell只会是一个没有逗号传递给case cell +: rest的字符串。对于implicitly[Parser[H]].apply(cell),这意味着第一个单元格将尝试执行此操作:

PersonWrapper

显然无法解析。为了使嵌套解析器起作用,在将implicitly[Parser[PersonWrapper]].apply("kevin") 应用于它们之前,您需要一些方法将单元格组合在一起。