Skip to content

Commit

Permalink
workaround for a possible scala bug in show for value class. (#1804)
Browse files Browse the repository at this point in the history
* workaround for a possible scala bug

* renamed to cshow

* hand rolling type class boilerplate

* minor

* move tests to scala 2.11+ to avoid 6260 in 2.10
  • Loading branch information
kailuowang authored Aug 11, 2017
1 parent 3238de6 commit 41402a8
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 8 deletions.
9 changes: 8 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,14 @@ lazy val commonSettings = Seq(
// workaround for https://github.com/scalastyle/scalastyle-sbt-plugin/issues/47
scalastyleSources in Compile ++= (unmanagedSourceDirectories in Compile).value,
ivyConfigurations += config("compile-time").hide,
unmanagedClasspath in Compile ++= update.value.select(configurationFilter("compile-time"))
unmanagedClasspath in Compile ++= update.value.select(configurationFilter("compile-time")),
unmanagedSourceDirectories in Test ++= {
val bd = baseDirectory.value
if (CrossVersion.partialVersion(scalaVersion.value) exists (_._2 >= 11))
CrossType.Pure.sharedSrcDir(bd, "test").toList map (f => file(f.getPath + "-2.11+"))
else
Nil
}
) ++ warnUnusedImport ++ update2_12 ++ xlint


Expand Down
27 changes: 21 additions & 6 deletions core/src/main/scala/cats/Show.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package cats

import simulacrum.typeclass
import cats.functor.Contravariant

/**
Expand All @@ -10,16 +9,32 @@ import cats.functor.Contravariant
* made a toString method, a Show instance will only exist if someone
* explicitly provided one.
*/
@typeclass trait Show[T] extends Show.ContravariantShow[T] {
// duplicated so simulacrum knows it requires an instance of this trait
def show(t: T): String
}
trait Show[T] extends Show.ContravariantShow[T]

/**
* Hand rolling the type class boilerplate due to scala/bug#6260 and scala/bug#10458
*/
object Show {
trait ContravariantShow[-T] {

def apply[A](implicit instance: Show[A]): Show[A] = instance

trait ContravariantShow[-T] extends Serializable {
def show(t: T): String
}

trait Ops[A] {
def typeClassInstance: Show[A]
def self: A
def show: String = typeClassInstance.show(self)
}

trait ToShowOps {
implicit def toShow[A](target: A)(implicit tc: Show[A]): Ops[A] = new Ops[A] {
val self = target
val typeClassInstance = tc
}
}

/** creates an instance of [[Show]] using the provided function */
def show[A](f: A => String): Show[A] = new Show[A] {
def show(a: A): String = f(a)
Expand Down
25 changes: 25 additions & 0 deletions tests/src/test/scala-2.11+/cats/tests/RegressionTests.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cats
package tests


import ExtraRegressionTests._

class ExtraRegressionTests extends CatsSuite {
/**
* Placed here to work around scala/bug#6260 on scala 2.10
*/
test("#1802 duplicated method name") {
Show[First[String]]
}
}


object ExtraRegressionTests {
final case class First[A](getFirst: A) extends AnyVal
object First {
implicit def showInstance[A](implicit ev: Show[A]): Show[First[A]] = new Show[First[A]] {
override def show(f: First[A]): String = s"First(${ev.show(f.getFirst)})"
}
}

}
2 changes: 1 addition & 1 deletion tests/src/test/scala/cats/tests/RegressionTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package tests
import cats.data.{Const, NonEmptyList}

import scala.collection.mutable

class RegressionTests extends CatsSuite {

// toy state class
Expand Down Expand Up @@ -123,4 +122,5 @@ class RegressionTests extends CatsSuite {
NonEmptyList.of(6,7,8).traverse_(validate) should === (Either.left("6 is greater than 5"))
checkAndResetCount(1)
}

}

0 comments on commit 41402a8

Please sign in to comment.