Skip to content

Commit 4d35eed

Browse files
committed
#794: Derivation tools for external newtypes
1 parent 3a27000 commit 4d35eed

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package zio.prelude.newtypes
2+
3+
import zio.prelude.newtypes.derivation.derive
4+
import zio.prelude.{Newtype, Subtype}
5+
import zio.test._
6+
7+
object DerivationSpec extends DefaultRunnableSpec {
8+
trait Show[A] {
9+
def show(a: A): String
10+
}
11+
12+
implicit val showString: Show[String] = (a: String) => a
13+
14+
// these are imported from an external library - we have no control over them
15+
object External {
16+
object Secret extends Newtype[String]
17+
type Secret = Secret.Type
18+
19+
object Password extends Subtype[String]
20+
type Password = Password.Type
21+
}
22+
23+
import External._
24+
25+
override def spec: ZSpec[Environment, Failure] = suite("external derivation for newtypes")(
26+
test("works for Newtype") {
27+
val showSecret: Show[Secret] = derive
28+
assertTrue(showSecret.show(Secret("foo")) == "foo")
29+
},
30+
test("works for Subtype") {
31+
val showPassword: Show[Password] = derive
32+
assertTrue(showPassword.show(Password("foo")) == "foo")
33+
},
34+
testM("works with auto derivation") {
35+
typeCheck("""
36+
|import zio.prelude.newtypes.derivation.auto._
37+
|implicitly[Show[Secret]]
38+
|implicitly[Show[Password]]
39+
|""".stripMargin).absolve
40+
.as(assertCompletes)
41+
}
42+
)
43+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package zio.prelude.newtypes
2+
3+
import zio.prelude.Newtype
4+
5+
object derivation {
6+
def derive[A, STA <: Newtype[A], F[_]](implicit ev: STA <:< Newtype[A], typeClass: F[A]): F[STA#Type] =
7+
typeClass.asInstanceOf[F[STA#Type]]
8+
9+
trait Auto {
10+
implicit def auto[A, STA <: Newtype[A], F[_]](implicit ev: STA <:< Newtype[A], typeClass: F[A]): F[STA#Type] = {
11+
// the type parameters and implicits are needed for 2.11 compatibility
12+
derive[A, STA, F](ev, typeClass)
13+
}
14+
}
15+
object auto extends Auto
16+
}

0 commit comments

Comments
 (0)