Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug in Generic with non-standard case class field names #729

Closed
seanmcl opened this issue Jun 2, 2017 · 4 comments
Closed

Bug in Generic with non-standard case class field names #729

seanmcl opened this issue Jun 2, 2017 · 4 comments
Labels

Comments

@seanmcl
Copy link

seanmcl commented Jun 2, 2017

The following program generates the output

List(abc, abc)

rather than the expected

List(abc, 5)

The cause seems to be the fact that the field 'foo' is a prefix of field foo-foo. E.g. when I rename the 'foo' field to 'foo1' I get the expected output.

import shapeless._

trait Const[A] {
  def const(v: A): String
}

object Const {
  def apply[A](implicit F: Const[A]): Const[A] = F
  def instance[A](g: A => String): Const[A] = v => g(v)
}

trait Consts[A] {
  def consts(v: A): List[String]
}

object Consts {
  def apply[A](implicit F: Consts[A]): Consts[A] = F
  def instance[A](g: A => List[String]): Consts[A] = v => g(v)

  implicit val hnil: Consts[HNil] = instance(_ => Nil)

  implicit def hlist[H, T <: HList](implicit F: Const[H], G: Consts[T]): Consts[H :: T] =
    instance({ case h :: t => F.const(h) +: G.consts(t) })

  implicit def generic[A, R](implicit F: Generic.Aux[A, R], G: Consts[R]): Consts[A] =
    instance(v => G.consts(F.to(v)))
}

case class Foo(s: String)

object Foo {
  implicit val const: Const[Foo] = Const.instance(_.s)
}

case class Bar(`foo-foo`: Foo, foo: Foo)

object Scratch extends App {
  println(Consts[Bar].consts(Bar(Foo("abc"), Foo("5"))))
}

The bug does not manifest when you swap the field order.

A smaller example, though that uses scalaz is

import scalaz._, Scalaz._
import shapeless._

trait Consts[A] {
  def consts(v: A): List[String]
}

object Consts {
  def apply[A](implicit F: Consts[A]): Consts[A] = F
  def instance[A](g: A => List[String]): Consts[A] = v => g(v)

  implicit val hnil: Consts[HNil] = instance(_ => Nil)

  implicit def hlist[H, T <: HList](implicit F: Show[H], G: Consts[T]): Consts[H :: T] =
    instance({ case h :: t => F.shows(h) +: G.consts(t) })

  implicit def generic[A, R](implicit F: Generic.Aux[A, R], G: Consts[R]): Consts[A] =
    instance(v => G.consts(F.to(v)))
}

case class Foo(s: String)

object Foo {
  implicit val show: Show[Foo] = Show.shows(_.s)
}

case class Bar(`foo-foo`: Foo, foo: Foo)

object Scratch extends App {
  println(Consts[Bar].consts(Bar(Foo("abc"), Foo("5"))))
}
@milessabin milessabin added the Bug label Jun 13, 2017
@joroKr21
Copy link
Collaborator

joroKr21 commented Sep 9, 2017

Scala, go home you're drunk: scala/bug#8831

@milessabin
Copy link
Owner

@joroKr21 well spotted!

@seanmcl can you confirm that removing the identifier backticks resolves this issue?

@seanmcl
Copy link
Author

seanmcl commented Sep 17, 2017

Hi @milessabin. Yes, the bug requires the backticks.

@milessabin
Copy link
Owner

Thanks ... this is scala/bug#8831 then ... I'll close this now.

@milessabin milessabin added this to the shapeless-2.3.3 milestone Dec 30, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants