From 90836ca2970d257aeb0491dd6604f47d32f514f6 Mon Sep 17 00:00:00 2001 From: "Frank S. Thomas" Date: Fri, 20 Apr 2018 04:36:44 +0200 Subject: [PATCH 01/14] Add AsValueOf[A, B] type class A type class that converts the type `A` to a value of type `B`. --- .../timepit/refined/internal/AsValueOf.scala | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala new file mode 100644 index 000000000..2367f25e6 --- /dev/null +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala @@ -0,0 +1,21 @@ +package eu.timepit.refined.internal + +import shapeless.{Nat, Witness} +import shapeless.ops.nat.ToInt + +trait AsValueOf[A, B] { + def value: B +} + +object AsValueOf { + def instance[A, B](b: B): AsValueOf[A, B] = + new AsValueOf[A, B] { + override def value: B = b + } + + implicit def natAsValueOf[B, A <: Nat](implicit ta: ToInt[A], nb: Numeric[B]): AsValueOf[A, B] = + instance(nb.fromInt(ta.apply())) + + implicit def witAsValueOf[B, A <: B](implicit wa: Witness.Aux[A]): AsValueOf[A, B] = + instance(wa.value) +} From 4d1e61465e932b61ec63cc94e7dd966d8b555b51 Mon Sep 17 00:00:00 2001 From: "Frank S. Thomas" Date: Fri, 20 Apr 2018 04:43:09 +0200 Subject: [PATCH 02/14] Change the definition of MaxSize[N] ... to `type MaxSize[N] = Size[Interval.Closed[_0, N]]` and use `AsValueOf` for the `Arbitrary` instance of `Interval.Closed[L, H]` so that we can generate instances where the LUB of `L` and `H` is `Any` (as for example in ``Interval.Closed[_0, W.`10`.T]``). --- .../main/scala/eu/timepit/refined/collection.scala | 5 +++-- .../scala/eu/timepit/refined/scalacheck/numeric.scala | 11 ++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/collection.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/collection.scala index ee86bdf9e..6bf831488 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/collection.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/collection.scala @@ -6,8 +6,9 @@ import eu.timepit.refined.boolean.Not import eu.timepit.refined.collection._ import eu.timepit.refined.generic.Equal import eu.timepit.refined.internal.Resources -import eu.timepit.refined.numeric.{GreaterEqual, LessEqual} +import eu.timepit.refined.numeric.{GreaterEqual, Interval} import shapeless.Witness +import shapeless.nat._0 /** Module for collection predicates. */ object collection extends CollectionInference { @@ -86,7 +87,7 @@ object collection extends CollectionInference { * Predicate that checks if the size of a `Traversable` is less than * or equal to `N`. */ - type MaxSize[N] = Size[LessEqual[N]] + type MaxSize[N] = Size[Interval.Closed[_0, N]] /** Predicate that checks if a `Traversable` is not empty. */ type NonEmpty = Not[Empty] diff --git a/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala b/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala index 9a04e71ca..f604f145e 100644 --- a/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala +++ b/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala @@ -1,7 +1,7 @@ package eu.timepit.refined.scalacheck import eu.timepit.refined.api.{Max, Min, RefType, Validate} -import eu.timepit.refined.internal.Adjacent +import eu.timepit.refined.internal.{Adjacent, AsValueOf} import eu.timepit.refined.numeric._ import org.scalacheck.{Arbitrary, Gen} import org.scalacheck.Gen.Choose @@ -112,11 +112,12 @@ trait NumericInstances { ): Arbitrary[F[T, Interval.ClosedOpen[L, H]]] = rangeClosedOpenArbitrary(wl.value, wh.value) - implicit def intervalClosedArbitrary[F[_, _]: RefType, T: Numeric: Choose, L <: T, H <: T]( - implicit wl: Witness.Aux[L], - wh: Witness.Aux[H] + implicit def intervalClosedArbitrary[F[_, _]: RefType, T: Numeric: Choose, L, H]( + implicit + vl: AsValueOf[L, T], + vh: AsValueOf[H, T] ): Arbitrary[F[T, Interval.Closed[L, H]]] = - rangeClosedArbitrary(wl.value, wh.value) + rangeClosedArbitrary(vl.value, vh.value) /// The following functions are private because it is not guaranteed /// that they produce valid values according to the predicate `P`. From 3afc3a1891dde5ce17a19f2252a503e3ee72432d Mon Sep 17 00:00:00 2001 From: "Frank S. Thomas" Date: Fri, 20 Apr 2018 05:10:28 +0200 Subject: [PATCH 03/14] Remove duplicated numeric ScalaCheck instances The instances with `AsValueOf` works for both `Nat` and primitive types. --- build.sbt | 3 +- .../refined/types/StringTypesSpec.scala | 2 +- .../timepit/refined/scalacheck/numeric.scala | 106 ++++++------------ 3 files changed, 40 insertions(+), 71 deletions(-) diff --git a/build.sbt b/build.sbt index 3404b6938..dc8fe2e41 100644 --- a/build.sbt +++ b/build.sbt @@ -383,7 +383,8 @@ lazy val moduleJvmSettings = Def.settings( ProblemFilters.exclude[ReversedMissingMethodProblem]( "eu.timepit.refined.api.RefinedType.dealias"), ProblemFilters.exclude[ReversedMissingMethodProblem]( - "eu.timepit.refined.scalacheck.RefTypeInstances.checkArbitraryRefinedType") + "eu.timepit.refined.scalacheck.RefTypeInstances.checkArbitraryRefinedType"), + ProblemFilters.exclude[DirectMissingMethodProblem]("eu.timepit.refined.scalacheck.*") ) } ) diff --git a/modules/core/shared/src/test/scala/eu/timepit/refined/types/StringTypesSpec.scala b/modules/core/shared/src/test/scala/eu/timepit/refined/types/StringTypesSpec.scala index d8754b682..101c04522 100644 --- a/modules/core/shared/src/test/scala/eu/timepit/refined/types/StringTypesSpec.scala +++ b/modules/core/shared/src/test/scala/eu/timepit/refined/types/StringTypesSpec.scala @@ -26,7 +26,7 @@ class StringTypesSpec extends Properties("StringTypes") { property("""FString3.from("abcd")""") = secure { val str = "abcd" FString3.from(str) ?= Left( - "Predicate taking size(abcd) = 4 failed: Predicate (4 > 3) did not fail.") + "Predicate taking size(abcd) = 4 failed: Right predicate of (!(4 < 0) && !(4 > 3)) failed: Predicate (4 > 3) did not fail.") } property("""FString3.truncate(str)""") = forAll { (str: String) => diff --git a/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala b/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala index f604f145e..da6d18e42 100644 --- a/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala +++ b/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala @@ -5,8 +5,6 @@ import eu.timepit.refined.internal.{Adjacent, AsValueOf} import eu.timepit.refined.numeric._ import org.scalacheck.{Arbitrary, Gen} import org.scalacheck.Gen.Choose -import shapeless.{Nat, Witness} -import shapeless.ops.nat.ToInt /** * Module that provides `Arbitrary` instances and generators for @@ -31,86 +29,56 @@ trait NumericInstances { /// - implicit def lessArbitraryWit[F[_, _]: RefType, T: Numeric: Choose: Adjacent, N <: T]( - implicit min: Min[T], - wn: Witness.Aux[N] - ): Arbitrary[F[T, Less[N]]] = - rangeClosedOpenArbitrary(min.min, wn.value) - - implicit def lessArbitraryNat[F[_, _]: RefType, T: Choose: Adjacent, N <: Nat]( - implicit min: Min[T], - nt: Numeric[T], - tn: ToInt[N] + implicit def lessArbitrary[F[_, _]: RefType, T: Numeric: Choose: Adjacent, N]( + implicit + min: Min[T], + vn: AsValueOf[N, T] ): Arbitrary[F[T, Less[N]]] = - rangeClosedOpenArbitrary(min.min, nt.fromInt(tn())) + rangeClosedOpenArbitrary(min.min, vn.value) - implicit def lessEqualArbitraryWit[F[_, _]: RefType, T: Numeric: Choose, N <: T]( - implicit min: Min[T], - wn: Witness.Aux[N] - ): Arbitrary[F[T, LessEqual[N]]] = - rangeClosedArbitrary(min.min, wn.value) - - implicit def lessEqualArbitraryNat[F[_, _]: RefType, T: Choose, N <: Nat]( - implicit min: Min[T], - nt: Numeric[T], - tn: ToInt[N] + implicit def lessEqualArbitrary[F[_, _]: RefType, T: Numeric: Choose, N]( + implicit + min: Min[T], + vn: AsValueOf[N, T] ): Arbitrary[F[T, LessEqual[N]]] = - rangeClosedArbitrary(min.min, nt.fromInt(tn())) + rangeClosedArbitrary(min.min, vn.value) - implicit def greaterArbitraryWit[F[_, _]: RefType, T: Numeric: Choose: Adjacent, N <: T]( - implicit max: Max[T], - wn: Witness.Aux[N] - ): Arbitrary[F[T, Greater[N]]] = - rangeOpenClosedArbitrary(wn.value, max.max) - - implicit def greaterArbitraryNat[F[_, _]: RefType, T: Choose: Adjacent, N <: Nat]( - implicit max: Max[T], - nt: Numeric[T], - tn: ToInt[N] + implicit def greaterArbitrary[F[_, _]: RefType, T: Numeric: Choose: Adjacent, N]( + implicit + max: Max[T], + vn: AsValueOf[N, T] ): Arbitrary[F[T, Greater[N]]] = - rangeOpenClosedArbitrary(nt.fromInt(tn()), max.max) + rangeOpenClosedArbitrary(vn.value, max.max) - implicit def greaterEqualArbitraryWit[F[_, _]: RefType, T: Numeric: Choose, N <: T]( - implicit max: Max[T], - wn: Witness.Aux[N] - ): Arbitrary[F[T, GreaterEqual[N]]] = - rangeClosedArbitrary(wn.value, max.max) - - implicit def greaterEqualArbitraryNat[F[_, _]: RefType, T: Choose, N <: Nat]( - implicit max: Max[T], - nt: Numeric[T], - tn: ToInt[N] + implicit def greaterEqualArbitraryWit[F[_, _]: RefType, T: Numeric: Choose, N]( + implicit + max: Max[T], + vn: AsValueOf[N, T] ): Arbitrary[F[T, GreaterEqual[N]]] = - rangeClosedArbitrary(nt.fromInt(tn()), max.max) + rangeClosedArbitrary(vn.value, max.max) /// - implicit def intervalOpenArbitrary[F[_, _]: RefType, - T: Numeric: Choose: Adjacent, - L <: T, - H <: T]( - implicit wl: Witness.Aux[L], - wh: Witness.Aux[H] + implicit def intervalOpenArbitrary[F[_, _]: RefType, T: Numeric: Choose: Adjacent, L, H]( + implicit + vl: AsValueOf[L, T], + vh: AsValueOf[H, T] ): Arbitrary[F[T, Interval.Open[L, H]]] = - rangeOpenArbitrary(wl.value, wh.value) - - implicit def intervalOpenClosedArbitrary[F[_, _]: RefType, - T: Numeric: Choose: Adjacent, - L <: T, - H <: T]( - implicit wl: Witness.Aux[L], - wh: Witness.Aux[H] + rangeOpenArbitrary(vl.value, vh.value) + + implicit def intervalOpenClosedArbitrary[F[_, _]: RefType, T: Numeric: Choose: Adjacent, L, H]( + implicit + vl: AsValueOf[L, T], + vh: AsValueOf[H, T] ): Arbitrary[F[T, Interval.OpenClosed[L, H]]] = - rangeOpenClosedArbitrary(wl.value, wh.value) - - implicit def intervalClosedOpenArbitrary[F[_, _]: RefType, - T: Numeric: Choose: Adjacent, - L <: T, - H <: T]( - implicit wl: Witness.Aux[L], - wh: Witness.Aux[H] + rangeOpenClosedArbitrary(vl.value, vh.value) + + implicit def intervalClosedOpenArbitrary[F[_, _]: RefType, T: Numeric: Choose: Adjacent, L, H]( + implicit + vl: AsValueOf[L, T], + vh: AsValueOf[H, T] ): Arbitrary[F[T, Interval.ClosedOpen[L, H]]] = - rangeClosedOpenArbitrary(wl.value, wh.value) + rangeClosedOpenArbitrary(vl.value, vh.value) implicit def intervalClosedArbitrary[F[_, _]: RefType, T: Numeric: Choose, L, H]( implicit From 80474479aab52f1659a7950329f91f138c9e0935 Mon Sep 17 00:00:00 2001 From: "Frank S. Thomas" Date: Fri, 20 Apr 2018 06:21:23 +0200 Subject: [PATCH 04/14] Unify duplicated Equal instances --- build.sbt | 8 ++++- .../scala/eu/timepit/refined/generic.scala | 34 +++++-------------- .../timepit/refined/internal/AsValueOf.scala | 23 +++++++++---- .../timepit/refined/scalacheck/numeric.scala | 18 +++++----- 4 files changed, 41 insertions(+), 42 deletions(-) diff --git a/build.sbt b/build.sbt index dc8fe2e41..c9ecdece1 100644 --- a/build.sbt +++ b/build.sbt @@ -384,7 +384,13 @@ lazy val moduleJvmSettings = Def.settings( "eu.timepit.refined.api.RefinedType.dealias"), ProblemFilters.exclude[ReversedMissingMethodProblem]( "eu.timepit.refined.scalacheck.RefTypeInstances.checkArbitraryRefinedType"), - ProblemFilters.exclude[DirectMissingMethodProblem]("eu.timepit.refined.scalacheck.*") + ProblemFilters.exclude[DirectMissingMethodProblem]("eu.timepit.refined.scalacheck.*"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "eu.timepit.refined.GenericInference.equalValidateInferenceWit"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "eu.timepit.refined.GenericInference.equalValidateInferenceNat"), + ProblemFilters.exclude[ReversedMissingMethodProblem]( + "eu.timepit.refined.GenericInference.equalValidateInference") ) } ) diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/generic.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/generic.scala index 598e39e2e..aba4c2458 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/generic.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/generic.scala @@ -3,10 +3,10 @@ package eu.timepit.refined import eu.timepit.refined.api.{Inference, Validate} import eu.timepit.refined.api.Inference.==> import eu.timepit.refined.generic._ +import eu.timepit.refined.internal.AsValueOf import shapeless._ import shapeless.ops.coproduct.ToHList import shapeless.ops.hlist.ToList -import shapeless.ops.nat.ToInt import shapeless.ops.record.Keys /** Module for generic predicates. */ @@ -36,19 +36,10 @@ object generic extends GenericInference { final case class Supertype[U]() object Equal { - implicit def equalValidateWit[T, U <: T]( - implicit wu: Witness.Aux[U] + implicit def equalValidate[T, U]( + implicit vu: AsValueOf[U, T] ): Validate.Plain[T, Equal[U]] = - Validate.fromPredicate(_ == wu.value, t => s"($t == ${wu.value})", Equal(wu.value)) - - implicit def equalValidateNat[N <: Nat, T]( - implicit tn: ToInt[N], - wn: Witness.Aux[N], - nt: Numeric[T] - ): Validate.Plain[T, Equal[N]] = { - val n = nt.fromInt(tn()) - Validate.fromPredicate(_ == n, t => s"($t == $n)", Equal(wn.value)) - } + Validate.fromPredicate(_ == vu.snd, t => s"($t == ${vu.snd})", Equal(vu.fst)) } object ConstructorNames { @@ -105,17 +96,10 @@ object generic extends GenericInference { private[refined] trait GenericInference { - implicit def equalValidateInferenceWit[T, U <: T, P]( - implicit v: Validate[T, P], - wu: Witness.Aux[U] + implicit def equalValidateInference[T, U, P]( + implicit + v: Validate[T, P], + wu: AsValueOf[U, T] ): Equal[U] ==> P = - Inference(v.isValid(wu.value), s"equalValidateInferenceWit(${v.showExpr(wu.value)})") - - implicit def equalValidateInferenceNat[T, N <: Nat, P]( - implicit v: Validate[T, P], - nt: Numeric[T], - tn: ToInt[N] - ): Equal[N] ==> P = - Inference(v.isValid(nt.fromInt(tn())), - s"equalValidateInferenceNat(${v.showExpr(nt.fromInt(tn()))})") + Inference(v.isValid(wu.snd), s"equalValidateInference(${v.showExpr(wu.snd)})") } diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala index 2367f25e6..e75e3fa1d 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala @@ -4,18 +4,27 @@ import shapeless.{Nat, Witness} import shapeless.ops.nat.ToInt trait AsValueOf[A, B] { - def value: B + def fst: A + def snd: B } object AsValueOf { - def instance[A, B](b: B): AsValueOf[A, B] = + def instance[A, B](a: A, b: B): AsValueOf[A, B] = new AsValueOf[A, B] { - override def value: B = b + override def fst: A = a + override def snd: B = b } - implicit def natAsValueOf[B, A <: Nat](implicit ta: ToInt[A], nb: Numeric[B]): AsValueOf[A, B] = - instance(nb.fromInt(ta.apply())) + implicit def natAsValueOf[B, A <: Nat]( + implicit + wa: Witness.Aux[A], + ta: ToInt[A], + nb: Numeric[B] + ): AsValueOf[A, B] = + instance(wa.value, nb.fromInt(ta.apply())) - implicit def witAsValueOf[B, A <: B](implicit wa: Witness.Aux[A]): AsValueOf[A, B] = - instance(wa.value) + implicit def witAsValueOf[B, A <: B]( + implicit wa: Witness.Aux[A] + ): AsValueOf[A, B] = + instance(wa.value, wa.value) } diff --git a/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala b/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala index da6d18e42..41240c36b 100644 --- a/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala +++ b/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala @@ -34,28 +34,28 @@ trait NumericInstances { min: Min[T], vn: AsValueOf[N, T] ): Arbitrary[F[T, Less[N]]] = - rangeClosedOpenArbitrary(min.min, vn.value) + rangeClosedOpenArbitrary(min.min, vn.snd) implicit def lessEqualArbitrary[F[_, _]: RefType, T: Numeric: Choose, N]( implicit min: Min[T], vn: AsValueOf[N, T] ): Arbitrary[F[T, LessEqual[N]]] = - rangeClosedArbitrary(min.min, vn.value) + rangeClosedArbitrary(min.min, vn.snd) implicit def greaterArbitrary[F[_, _]: RefType, T: Numeric: Choose: Adjacent, N]( implicit max: Max[T], vn: AsValueOf[N, T] ): Arbitrary[F[T, Greater[N]]] = - rangeOpenClosedArbitrary(vn.value, max.max) + rangeOpenClosedArbitrary(vn.snd, max.max) - implicit def greaterEqualArbitraryWit[F[_, _]: RefType, T: Numeric: Choose, N]( + implicit def greaterEqualArbitrary[F[_, _]: RefType, T: Numeric: Choose, N]( implicit max: Max[T], vn: AsValueOf[N, T] ): Arbitrary[F[T, GreaterEqual[N]]] = - rangeClosedArbitrary(vn.value, max.max) + rangeClosedArbitrary(vn.snd, max.max) /// @@ -64,28 +64,28 @@ trait NumericInstances { vl: AsValueOf[L, T], vh: AsValueOf[H, T] ): Arbitrary[F[T, Interval.Open[L, H]]] = - rangeOpenArbitrary(vl.value, vh.value) + rangeOpenArbitrary(vl.snd, vh.snd) implicit def intervalOpenClosedArbitrary[F[_, _]: RefType, T: Numeric: Choose: Adjacent, L, H]( implicit vl: AsValueOf[L, T], vh: AsValueOf[H, T] ): Arbitrary[F[T, Interval.OpenClosed[L, H]]] = - rangeOpenClosedArbitrary(vl.value, vh.value) + rangeOpenClosedArbitrary(vl.snd, vh.snd) implicit def intervalClosedOpenArbitrary[F[_, _]: RefType, T: Numeric: Choose: Adjacent, L, H]( implicit vl: AsValueOf[L, T], vh: AsValueOf[H, T] ): Arbitrary[F[T, Interval.ClosedOpen[L, H]]] = - rangeClosedOpenArbitrary(vl.value, vh.value) + rangeClosedOpenArbitrary(vl.snd, vh.snd) implicit def intervalClosedArbitrary[F[_, _]: RefType, T: Numeric: Choose, L, H]( implicit vl: AsValueOf[L, T], vh: AsValueOf[H, T] ): Arbitrary[F[T, Interval.Closed[L, H]]] = - rangeClosedArbitrary(vl.value, vh.value) + rangeClosedArbitrary(vl.snd, vh.snd) /// The following functions are private because it is not guaranteed /// that they produce valid values according to the predicate `P`. From 3515e0cc945e4b4da687dee0a8abeb9e02068859 Mon Sep 17 00:00:00 2001 From: "Frank S. Thomas" Date: Fri, 20 Apr 2018 06:40:20 +0200 Subject: [PATCH 05/14] Unify numeric Validate instances --- .../scala/eu/timepit/refined/numeric.scala | 67 +++++-------------- 1 file changed, 16 insertions(+), 51 deletions(-) diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/numeric.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/numeric.scala index dd25820b6..326bdbfe1 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/numeric.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/numeric.scala @@ -3,6 +3,7 @@ package eu.timepit.refined import eu.timepit.refined.api.{Inference, Validate} import eu.timepit.refined.api.Inference.==> import eu.timepit.refined.boolean.{And, Not} +import eu.timepit.refined.internal.AsValueOf import eu.timepit.refined.numeric._ import shapeless.{Nat, Witness} import shapeless.nat.{_0, _2} @@ -86,70 +87,34 @@ object numeric extends NumericInference { } object Less { - implicit def lessValidateWit[T, N <: T]( - implicit wn: Witness.Aux[N], + implicit def lessValidate[T, N]( + implicit + vn: AsValueOf[N, T], nt: Numeric[T] ): Validate.Plain[T, Less[N]] = - Validate.fromPredicate(t => nt.lt(t, wn.value), t => s"($t < ${wn.value})", Less(wn.value)) - - implicit def lessValidateNat[N <: Nat, T]( - implicit tn: ToInt[N], - wn: Witness.Aux[N], - nt: Numeric[T] - ): Validate.Plain[T, Less[N]] = - Validate.fromPredicate(t => nt.toDouble(t) < tn(), t => s"($t < ${tn()})", Less(wn.value)) + Validate.fromPredicate(t => nt.lt(t, vn.snd), t => s"($t < ${vn.snd})", Less(vn.fst)) } object Greater { - implicit def greaterValidateWit[T, N <: T]( - implicit wn: Witness.Aux[N], - nt: Numeric[T] - ): Validate.Plain[T, Greater[N]] = - Validate.fromPredicate(t => nt.gt(t, wn.value), t => s"($t > ${wn.value})", Greater(wn.value)) - - implicit def greaterValidateNat[N <: Nat, T]( - implicit tn: ToInt[N], - wn: Witness.Aux[N], + implicit def greaterValidate[T, N]( + implicit + vn: AsValueOf[N, T], nt: Numeric[T] ): Validate.Plain[T, Greater[N]] = - Validate.fromPredicate(t => nt.toDouble(t) > tn(), t => s"($t > ${tn()})", Greater(wn.value)) + Validate.fromPredicate(t => nt.gt(t, vn.snd), t => s"($t > ${vn.snd})", Greater(vn.fst)) } object Modulo { - implicit def moduloValidateWitIntegral[T, N <: T, O <: T]( - implicit wn: Witness.Aux[N], - wo: Witness.Aux[O], - it: Integral[T] - ): Validate.Plain[T, Modulo[N, O]] = - Validate.fromPredicate( - t => it.rem(t, wn.value) == wo.value, - t => s"($t % ${wn.value} == ${wo.value})", - Modulo(wn.value, wo.value) - ) - - implicit def moduloValidateNatIntegral[N <: Nat, O <: Nat, T]( - implicit tn: ToInt[N], - to: ToInt[O], - wn: Witness.Aux[N], - wo: Witness.Aux[O], - it: Integral[T] - ): Validate.Plain[T, Modulo[N, O]] = - Validate.fromPredicate( - t => it.rem(t, it.fromInt(tn())) == it.fromInt(to()), - t => s"($t % ${tn()} == ${to()})", - Modulo(wn.value, wo.value) - ) - - implicit def moduloValidateWitNatIntegral[T, N <: T, O <: Nat]( - implicit wn: Witness.Aux[N], - to: ToInt[O], - wo: Witness.Aux[O], + implicit def moduloValidate[T, N, O]( + implicit + vn: AsValueOf[N, T], + vo: AsValueOf[O, T], it: Integral[T] ): Validate.Plain[T, Modulo[N, O]] = Validate.fromPredicate( - t => it.rem(t, wn.value) == it.fromInt(to()), - t => s"($t % ${wn.value} == ${to()})", - Modulo(wn.value, wo.value) + t => it.rem(t, vn.snd) == vo.snd, + t => s"($t % ${vn.snd} == ${vo.snd})", + Modulo(vn.fst, vo.fst) ) } } From a80f35489506d9f6ddab272431e4a7bbf7b44a79 Mon Sep 17 00:00:00 2001 From: "Frank S. Thomas" Date: Fri, 20 Apr 2018 15:57:26 +0200 Subject: [PATCH 06/14] Unify some Min/Max instances --- build.sbt | 18 ++++++++++++++++- .../scala/eu/timepit/refined/api/Max.scala | 20 ++++++------------- .../scala/eu/timepit/refined/api/Min.scala | 20 ++++++------------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/build.sbt b/build.sbt index c9ecdece1..50823ec5e 100644 --- a/build.sbt +++ b/build.sbt @@ -390,7 +390,23 @@ lazy val moduleJvmSettings = Def.settings( ProblemFilters.exclude[DirectMissingMethodProblem]( "eu.timepit.refined.GenericInference.equalValidateInferenceNat"), ProblemFilters.exclude[ReversedMissingMethodProblem]( - "eu.timepit.refined.GenericInference.equalValidateInference") + "eu.timepit.refined.GenericInference.equalValidateInference"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "eu.timepit.refined.api.Max.lessEqualMaxWit"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "eu.timepit.refined.api.Max.lessEqualMaxNat"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "eu.timepit.refined.api.MaxInstances.lessEqualMaxWit"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "eu.timepit.refined.api.MaxInstances.lessEqualMaxNat"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "eu.timepit.refined.api.MinInstances.greaterEqualMinWit"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "eu.timepit.refined.api.MinInstances.greaterEqualMinNat"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "eu.timepit.refined.api.Min.greaterEqualMinWit"), + ProblemFilters.exclude[DirectMissingMethodProblem]( + "eu.timepit.refined.api.Min.greaterEqualMinNat") ) } ) diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/api/Max.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/api/Max.scala index a951adbc4..eec9c38a0 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/api/Max.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/api/Max.scala @@ -1,10 +1,8 @@ package eu.timepit.refined.api import eu.timepit.refined.boolean.And -import eu.timepit.refined.internal.Adjacent +import eu.timepit.refined.internal.{Adjacent, AsValueOf} import eu.timepit.refined.numeric.{Greater, GreaterEqual, Less, LessEqual} -import shapeless.{Nat, Witness} -import shapeless.ops.nat.ToInt /** * Type class defining the maximum value of a given type @@ -37,18 +35,12 @@ trait MaxInstances extends LowPriorityMaxInstances { ): Max[F[T, GreaterEqual[N]]] = Max.instance(rt.unsafeWrap(mt.max)) - implicit def lessEqualMaxWit[F[_, _], T, N <: T]( - implicit rt: RefType[F], - wn: Witness.Aux[N] - ): Max[F[T, LessEqual[N]]] = - Max.instance(rt.unsafeWrap(wn.value)) - - implicit def lessEqualMaxNat[F[_, _], T, N <: Nat]( - implicit rt: RefType[F], - tn: ToInt[N], - nt: Numeric[T] + implicit def lessEqualMax[F[_, _], T, N]( + implicit + rt: RefType[F], + vn: AsValueOf[N, T] ): Max[F[T, LessEqual[N]]] = - Max.instance(rt.unsafeWrap(nt.fromInt(tn()))) + Max.instance(rt.unsafeWrap(vn.snd)) implicit def lessMax[F[_, _], T, N]( implicit rt: RefType[F], diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/api/Min.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/api/Min.scala index fea5f4b21..345fc00e6 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/api/Min.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/api/Min.scala @@ -1,10 +1,8 @@ package eu.timepit.refined.api import eu.timepit.refined.boolean.And -import eu.timepit.refined.internal.Adjacent +import eu.timepit.refined.internal.{Adjacent, AsValueOf} import eu.timepit.refined.numeric.{Greater, GreaterEqual, Less, LessEqual} -import shapeless.{Nat, Witness} -import shapeless.ops.nat.ToInt /** * Type class defining the minimum value of a given type @@ -37,18 +35,12 @@ trait MinInstances extends LowPriorityMinInstances { ): Min[F[T, LessEqual[N]]] = Min.instance(rt.unsafeWrap(mt.min)) - implicit def greaterEqualMinWit[F[_, _], T, N <: T]( - implicit rt: RefType[F], - wn: Witness.Aux[N] - ): Min[F[T, GreaterEqual[N]]] = - Min.instance(rt.unsafeWrap(wn.value)) - - implicit def greaterEqualMinNat[F[_, _], T, N <: Nat]( - implicit rt: RefType[F], - tn: ToInt[N], - nt: Numeric[T] + implicit def greaterEqualMin[F[_, _], T, N]( + implicit + rt: RefType[F], + vn: AsValueOf[N, T] ): Min[F[T, GreaterEqual[N]]] = - Min.instance(rt.unsafeWrap(nt.fromInt(tn()))) + Min.instance(rt.unsafeWrap(vn.snd)) implicit def greaterMin[F[_, _], T, N]( implicit rt: RefType[F], From 6da5b5181981848e658394c87e3766e1571d81ed Mon Sep 17 00:00:00 2001 From: "Frank S. Thomas" Date: Fri, 20 Apr 2018 16:30:10 +0200 Subject: [PATCH 07/14] More MiMa exceptions --- build.sbt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 50823ec5e..a387903a6 100644 --- a/build.sbt +++ b/build.sbt @@ -406,7 +406,11 @@ lazy val moduleJvmSettings = Def.settings( ProblemFilters.exclude[DirectMissingMethodProblem]( "eu.timepit.refined.api.Min.greaterEqualMinWit"), ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.api.Min.greaterEqualMinNat") + "eu.timepit.refined.api.Min.greaterEqualMinNat"), + ProblemFilters.exclude[ReversedMissingMethodProblem]( + "eu.timepit.refined.api.MinInstances.greaterEqualMin"), + ProblemFilters.exclude[ReversedMissingMethodProblem]( + "eu.timepit.refined.api.MaxInstances.lessEqualMax") ) } ) From dcadeff099d1d8656c33666722196f054fd4da26 Mon Sep 17 00:00:00 2001 From: "Frank S. Thomas" Date: Fri, 20 Apr 2018 18:08:29 +0200 Subject: [PATCH 08/14] Disable MiMa until 0.9.0 is released --- build.sbt | 96 +---------------------------------------------- latestVersion.sbt | 2 +- 2 files changed, 2 insertions(+), 96 deletions(-) diff --git a/build.sbt b/build.sbt index a387903a6..c69332623 100644 --- a/build.sbt +++ b/build.sbt @@ -317,101 +317,7 @@ lazy val moduleJvmSettings = Def.settings( mimaBinaryIssueFilters ++= { import com.typesafe.tools.mima.core._ Seq( - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "eu.timepit.refined.scalacheck.StringInstances.nonEmptyStringArbitrary"), - ProblemFilters.exclude[DirectMissingMethodProblem]("eu.timepit.refined.api.Refined.get"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.api.Refined.get$extension"), - ProblemFilters.exclude[MissingClassProblem]("eu.timepit.refined.util.time$"), - ProblemFilters.exclude[MissingClassProblem]("eu.timepit.refined.util.time"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.numeric.moduloValidateNat"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.numeric.moduloValidateWit"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.NumericValidate.moduloValidateNat"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.NumericValidate.moduloValidateWit"), - ProblemFilters.exclude[DirectMissingMethodProblem]("eu.timepit.refined.types.*"), - ProblemFilters.exclude[IncompatibleResultTypeProblem]("eu.timepit.refined.types.*"), - ProblemFilters.exclude[MissingClassProblem]("eu.timepit.refined.types.*"), - ProblemFilters.exclude[MissingTypesProblem]("eu.timepit.refined.types.*"), - ProblemFilters.exclude[ReversedMissingMethodProblem]("eu.timepit.refined.types.*"), - ProblemFilters.exclude[DirectMissingMethodProblem]("eu.timepit.refined.char.*"), - ProblemFilters.exclude[MissingClassProblem]("eu.timepit.refined.CharValidate"), - ProblemFilters.exclude[MissingTypesProblem]("eu.timepit.refined.char$*"), - ProblemFilters.exclude[DirectMissingMethodProblem]("eu.timepit.refined.boolean.*"), - ProblemFilters.exclude[MissingClassProblem]("eu.timepit.refined.BooleanValidate"), - ProblemFilters.exclude[MissingTypesProblem]("eu.timepit.refined.boolean$*"), - ProblemFilters.exclude[DirectMissingMethodProblem]("eu.timepit.refined.generic.*"), - ProblemFilters.exclude[MissingClassProblem]("eu.timepit.refined.GenericValidate"), - ProblemFilters.exclude[MissingTypesProblem]("eu.timepit.refined.generic$*"), - ProblemFilters.exclude[DirectMissingMethodProblem]("eu.timepit.refined.numeric.*"), - ProblemFilters.exclude[MissingClassProblem]("eu.timepit.refined.NumericValidate"), - ProblemFilters.exclude[MissingTypesProblem]("eu.timepit.refined.numeric*"), - ProblemFilters.exclude[DirectMissingMethodProblem]("eu.timepit.refined.string.*"), - ProblemFilters.exclude[MissingClassProblem]("eu.timepit.refined.StringValidate"), - ProblemFilters.exclude[MissingTypesProblem]("eu.timepit.refined.string*"), - ProblemFilters.exclude[DirectMissingMethodProblem]("eu.timepit.refined.collection.*"), - ProblemFilters.exclude[MissingClassProblem]("eu.timepit.refined.CollectionValidate"), - ProblemFilters.exclude[MissingTypesProblem]("eu.timepit.refined.collection*"), - ProblemFilters.exclude[DirectMissingMethodProblem]("eu.timepit.refined.string#IPv4.*"), - ProblemFilters.exclude[DirectMissingMethodProblem]("eu.timepit.refined.string#IPv6.*"), - ProblemFilters.exclude[MissingTypesProblem]("eu.timepit.refined.eval$"), - ProblemFilters.exclude[DirectMissingMethodProblem]("eu.timepit.refined.eval.evalValidate"), - ProblemFilters.exclude[MissingClassProblem]("eu.timepit.refined.EvalValidate"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.jsonpath.string.jsonPathValidate"), - ProblemFilters.exclude[MissingTypesProblem]("eu.timepit.refined.jsonpath.string$*"), - ProblemFilters.exclude[MissingClassProblem]("eu.timepit.refined.jsonpath.StringValidate"), - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "eu.timepit.refined.NumericInference.greaterEqualInference"), - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "eu.timepit.refined.NumericInference.lessEqualInference"), - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "eu.timepit.refined.scalacheck.StringInstances.stringSizeArbitrary"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "eu.timepit.refined.scalacheck.numeric.*"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]( - "eu.timepit.refined.scalacheck.NumericInstances.*"), - ProblemFilters.exclude[IncompatibleMethTypeProblem]("eu.timepit.refined.scalacheck.all.*"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.scalacheck.NumericInstances.*"), - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "eu.timepit.refined.scalacheck.NumericInstances.*"), - ProblemFilters.exclude[InheritedNewAbstractMethodProblem]("eu.timepit.refined.types.*"), - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "eu.timepit.refined.api.RefinedType.dealias"), - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "eu.timepit.refined.scalacheck.RefTypeInstances.checkArbitraryRefinedType"), - ProblemFilters.exclude[DirectMissingMethodProblem]("eu.timepit.refined.scalacheck.*"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.GenericInference.equalValidateInferenceWit"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.GenericInference.equalValidateInferenceNat"), - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "eu.timepit.refined.GenericInference.equalValidateInference"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.api.Max.lessEqualMaxWit"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.api.Max.lessEqualMaxNat"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.api.MaxInstances.lessEqualMaxWit"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.api.MaxInstances.lessEqualMaxNat"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.api.MinInstances.greaterEqualMinWit"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.api.MinInstances.greaterEqualMinNat"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.api.Min.greaterEqualMinWit"), - ProblemFilters.exclude[DirectMissingMethodProblem]( - "eu.timepit.refined.api.Min.greaterEqualMinNat"), - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "eu.timepit.refined.api.MinInstances.greaterEqualMin"), - ProblemFilters.exclude[ReversedMissingMethodProblem]( - "eu.timepit.refined.api.MaxInstances.lessEqualMax") - ) + ) } ) diff --git a/latestVersion.sbt b/latestVersion.sbt index 151b08868..9efc524c7 100644 --- a/latestVersion.sbt +++ b/latestVersion.sbt @@ -1,6 +1,6 @@ latestVersion in ThisBuild := "0.8.7" -latestVersionInSeries in ThisBuild := Some("0.8.7") +latestVersionInSeries in ThisBuild := None unreleasedModules in ThisBuild := Set( "refined-scopt", From 4e12f25110755e9cf0552b394d0bdf5ce73c6ca6 Mon Sep 17 00:00:00 2001 From: "Frank S. Thomas" Date: Fri, 20 Apr 2018 20:12:40 +0200 Subject: [PATCH 09/14] Unify some numeric Infernce instances --- .../timepit/refined/internal/AsValueOf.scala | 2 + .../scala/eu/timepit/refined/numeric.scala | 46 ++++++++----------- .../eu/timepit/refined/types/string.scala | 14 +++--- 3 files changed, 27 insertions(+), 35 deletions(-) diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala index e75e3fa1d..50a746186 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala @@ -9,6 +9,8 @@ trait AsValueOf[A, B] { } object AsValueOf { + def apply[A, B](implicit a: AsValueOf[A, B]): AsValueOf[A, B] = a + def instance[A, B](a: A, b: B): AsValueOf[A, B] = new AsValueOf[A, B] { override def fst: A = a diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/numeric.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/numeric.scala index 326bdbfe1..b1d85401d 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/numeric.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/numeric.scala @@ -5,7 +5,7 @@ import eu.timepit.refined.api.Inference.==> import eu.timepit.refined.boolean.{And, Not} import eu.timepit.refined.internal.AsValueOf import eu.timepit.refined.numeric._ -import shapeless.{Nat, Witness} +import shapeless.Nat import shapeless.nat.{_0, _2} import shapeless.ops.nat.ToInt @@ -121,46 +121,36 @@ object numeric extends NumericInference { private[refined] trait NumericInference { - implicit def lessInferenceWit[C, A <: C, B <: C]( - implicit wa: Witness.Aux[A], - wb: Witness.Aux[B], + implicit def lessInference[C, A, B]( + implicit + wa: AsValueOf[A, C], + wb: AsValueOf[B, C], nc: Numeric[C] ): Less[A] ==> Less[B] = - Inference(nc.lt(wa.value, wb.value), s"lessInferenceWit(${wa.value}, ${wb.value})") - - implicit def greaterInferenceWit[C, A <: C, B <: C]( - implicit wa: Witness.Aux[A], - wb: Witness.Aux[B], - nc: Numeric[C] - ): Greater[A] ==> Greater[B] = - Inference(nc.gt(wa.value, wb.value), s"greaterInferenceWit(${wa.value}, ${wb.value})") + Inference(nc.lt(wa.snd, wb.snd), s"lessInference(${wa.snd}, ${wb.snd})") implicit def lessInferenceNat[A <: Nat, B <: Nat]( - implicit ta: ToInt[A], + implicit + ta: ToInt[A], tb: ToInt[B] ): Less[A] ==> Less[B] = Inference(ta() < tb(), s"lessInferenceNat(${ta()}, ${tb()})") + implicit def greaterInference[C, A, B]( + implicit + wa: AsValueOf[A, C], + wb: AsValueOf[B, C], + nc: Numeric[C] + ): Greater[A] ==> Greater[B] = + Inference(nc.gt(wa.snd, wb.snd), s"greaterInference(${wa.snd}, ${wb.snd})") + implicit def greaterInferenceNat[A <: Nat, B <: Nat]( - implicit ta: ToInt[A], + implicit + ta: ToInt[A], tb: ToInt[B] ): Greater[A] ==> Greater[B] = Inference(ta() > tb(), s"greaterInferenceNat(${ta()}, ${tb()})") - implicit def lessInferenceWitNat[C, A <: C, B <: Nat]( - implicit wa: Witness.Aux[A], - tb: ToInt[B], - nc: Numeric[C] - ): Less[A] ==> Less[B] = - Inference(nc.lt(wa.value, nc.fromInt(tb())), s"lessInferenceWitNat(${wa.value}, ${tb()})") - - implicit def greaterInferenceWitNat[C, A <: C, B <: Nat]( - implicit wa: Witness.Aux[A], - tb: ToInt[B], - nc: Numeric[C] - ): Greater[A] ==> Greater[B] = - Inference(nc.gt(wa.value, nc.fromInt(tb())), s"greaterInferenceWitNat(${wa.value}, ${tb()})") - implicit def greaterEqualInference[A]: Greater[A] ==> GreaterEqual[A] = Inference(true, "greaterEqualInference") diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/types/string.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/types/string.scala index 508476642..6ffd4edea 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/types/string.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/types/string.scala @@ -3,8 +3,8 @@ package eu.timepit.refined.types import eu.timepit.refined.W import eu.timepit.refined.api.{Refined, RefinedType, RefinedTypeOps} import eu.timepit.refined.collection.{MaxSize, NonEmpty} +import eu.timepit.refined.internal.AsValueOf import eu.timepit.refined.string.MatchesRegex -import shapeless.Witness /** Module for `String` refined types. */ object string { @@ -13,15 +13,15 @@ object string { type FiniteString[N] = String Refined MaxSize[N] object FiniteString { - class FiniteStringOps[N <: Int]( + class FiniteStringOps[N]( implicit rt: RefinedType.AuxT[FiniteString[N], String], - wn: Witness.Aux[N] + vn: AsValueOf[N, Int] ) extends RefinedTypeOps[FiniteString[N], String] { /** The maximum length of a `FiniteString[N]`. */ - final val maxLength: N = - wn.value + final val maxLength: Int = + vn.snd /** * Creates a `FiniteString[N]` from `t` by truncating it @@ -32,10 +32,10 @@ object string { } /** Creates a "companion object" for `FiniteString[N]` with a fixed `N`. */ - def apply[N <: Int]( + def apply[N]( implicit rt: RefinedType.AuxT[FiniteString[N], String], - wn: Witness.Aux[N] + vn: AsValueOf[N, Int] ): FiniteStringOps[N] = new FiniteStringOps[N] } From f9cb98270189499c36341ddab6a3041a94be2aa5 Mon Sep 17 00:00:00 2001 From: "Frank S. Thomas" Date: Fri, 20 Apr 2018 21:48:49 +0200 Subject: [PATCH 10/14] Rename AsValueOf to WitnessAs --- .../scala/eu/timepit/refined/api/Max.scala | 6 +-- .../scala/eu/timepit/refined/api/Min.scala | 6 +-- .../scala/eu/timepit/refined/generic.scala | 8 ++-- .../timepit/refined/internal/AsValueOf.scala | 32 -------------- .../timepit/refined/internal/WitnessAs.scala | 42 +++++++++++++++++++ .../scala/eu/timepit/refined/numeric.scala | 28 ++++++------- .../eu/timepit/refined/types/string.scala | 8 ++-- .../timepit/refined/scalacheck/numeric.scala | 42 +++++++++---------- .../scalacheck/StringArbitrarySpec.scala | 3 ++ 9 files changed, 94 insertions(+), 81 deletions(-) delete mode 100644 modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala create mode 100644 modules/core/shared/src/main/scala/eu/timepit/refined/internal/WitnessAs.scala diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/api/Max.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/api/Max.scala index eec9c38a0..fd43c02bf 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/api/Max.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/api/Max.scala @@ -1,7 +1,7 @@ package eu.timepit.refined.api import eu.timepit.refined.boolean.And -import eu.timepit.refined.internal.{Adjacent, AsValueOf} +import eu.timepit.refined.internal.{Adjacent, WitnessAs} import eu.timepit.refined.numeric.{Greater, GreaterEqual, Less, LessEqual} /** @@ -38,9 +38,9 @@ trait MaxInstances extends LowPriorityMaxInstances { implicit def lessEqualMax[F[_, _], T, N]( implicit rt: RefType[F], - vn: AsValueOf[N, T] + wn: WitnessAs[N, T] ): Max[F[T, LessEqual[N]]] = - Max.instance(rt.unsafeWrap(vn.snd)) + Max.instance(rt.unsafeWrap(wn.snd)) implicit def lessMax[F[_, _], T, N]( implicit rt: RefType[F], diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/api/Min.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/api/Min.scala index 345fc00e6..7909196c2 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/api/Min.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/api/Min.scala @@ -1,7 +1,7 @@ package eu.timepit.refined.api import eu.timepit.refined.boolean.And -import eu.timepit.refined.internal.{Adjacent, AsValueOf} +import eu.timepit.refined.internal.{Adjacent, WitnessAs} import eu.timepit.refined.numeric.{Greater, GreaterEqual, Less, LessEqual} /** @@ -38,9 +38,9 @@ trait MinInstances extends LowPriorityMinInstances { implicit def greaterEqualMin[F[_, _], T, N]( implicit rt: RefType[F], - vn: AsValueOf[N, T] + wn: WitnessAs[N, T] ): Min[F[T, GreaterEqual[N]]] = - Min.instance(rt.unsafeWrap(vn.snd)) + Min.instance(rt.unsafeWrap(wn.snd)) implicit def greaterMin[F[_, _], T, N]( implicit rt: RefType[F], diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/generic.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/generic.scala index aba4c2458..3664615c9 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/generic.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/generic.scala @@ -3,7 +3,7 @@ package eu.timepit.refined import eu.timepit.refined.api.{Inference, Validate} import eu.timepit.refined.api.Inference.==> import eu.timepit.refined.generic._ -import eu.timepit.refined.internal.AsValueOf +import eu.timepit.refined.internal.WitnessAs import shapeless._ import shapeless.ops.coproduct.ToHList import shapeless.ops.hlist.ToList @@ -37,9 +37,9 @@ object generic extends GenericInference { object Equal { implicit def equalValidate[T, U]( - implicit vu: AsValueOf[U, T] + implicit wu: WitnessAs[U, T] ): Validate.Plain[T, Equal[U]] = - Validate.fromPredicate(_ == vu.snd, t => s"($t == ${vu.snd})", Equal(vu.fst)) + Validate.fromPredicate(_ == wu.snd, t => s"($t == ${wu.snd})", Equal(wu.fst)) } object ConstructorNames { @@ -99,7 +99,7 @@ private[refined] trait GenericInference { implicit def equalValidateInference[T, U, P]( implicit v: Validate[T, P], - wu: AsValueOf[U, T] + wu: WitnessAs[U, T] ): Equal[U] ==> P = Inference(v.isValid(wu.snd), s"equalValidateInference(${v.showExpr(wu.snd)})") } diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala deleted file mode 100644 index 50a746186..000000000 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/internal/AsValueOf.scala +++ /dev/null @@ -1,32 +0,0 @@ -package eu.timepit.refined.internal - -import shapeless.{Nat, Witness} -import shapeless.ops.nat.ToInt - -trait AsValueOf[A, B] { - def fst: A - def snd: B -} - -object AsValueOf { - def apply[A, B](implicit a: AsValueOf[A, B]): AsValueOf[A, B] = a - - def instance[A, B](a: A, b: B): AsValueOf[A, B] = - new AsValueOf[A, B] { - override def fst: A = a - override def snd: B = b - } - - implicit def natAsValueOf[B, A <: Nat]( - implicit - wa: Witness.Aux[A], - ta: ToInt[A], - nb: Numeric[B] - ): AsValueOf[A, B] = - instance(wa.value, nb.fromInt(ta.apply())) - - implicit def witAsValueOf[B, A <: B]( - implicit wa: Witness.Aux[A] - ): AsValueOf[A, B] = - instance(wa.value, wa.value) -} diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/internal/WitnessAs.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/internal/WitnessAs.scala new file mode 100644 index 000000000..4133297d3 --- /dev/null +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/internal/WitnessAs.scala @@ -0,0 +1,42 @@ +package eu.timepit.refined.internal + +import shapeless.{Nat, Witness} +import shapeless.ops.nat.ToInt + +/** + * `WitnessAs[A, B]` provides the singleton value of type `A` in `fst` + * and `fst` converted to type `B` in `snd`. + * + * The purpose of this type class is to write numeric type class + * instances that work with both literal singleton types and + * `shapeless.Nat`. + * + * Example: {{{ + * scala> import eu.timepit.refined.W + * | import shapeless.nat._5 + * + * scala> WitnessAs[W.`5`.T, Int] + * res1: WitnessAs[W.`5`.T, Int] = WitnessAs(5,5) + * + * scala> WitnessAs[_5, Int] + * res2: WitnessAs[_5, Int] = WitnessAs(Succ(),5) + * }}} + */ +final case class WitnessAs[A, B](fst: A, snd: B) + +object WitnessAs { + def apply[A, B](implicit ev: WitnessAs[A, B]): WitnessAs[A, B] = ev + + implicit def natWitnessAs[B, A <: Nat]( + implicit + wa: Witness.Aux[A], + ta: ToInt[A], + nb: Numeric[B] + ): WitnessAs[A, B] = + WitnessAs(wa.value, nb.fromInt(ta.apply())) + + implicit def singletonWitnessAs[B, A <: B]( + implicit wa: Witness.Aux[A] + ): WitnessAs[A, B] = + WitnessAs(wa.value, wa.value) +} diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/numeric.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/numeric.scala index b1d85401d..3f1467139 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/numeric.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/numeric.scala @@ -3,7 +3,7 @@ package eu.timepit.refined import eu.timepit.refined.api.{Inference, Validate} import eu.timepit.refined.api.Inference.==> import eu.timepit.refined.boolean.{And, Not} -import eu.timepit.refined.internal.AsValueOf +import eu.timepit.refined.internal.WitnessAs import eu.timepit.refined.numeric._ import shapeless.Nat import shapeless.nat.{_0, _2} @@ -89,32 +89,32 @@ object numeric extends NumericInference { object Less { implicit def lessValidate[T, N]( implicit - vn: AsValueOf[N, T], + wn: WitnessAs[N, T], nt: Numeric[T] ): Validate.Plain[T, Less[N]] = - Validate.fromPredicate(t => nt.lt(t, vn.snd), t => s"($t < ${vn.snd})", Less(vn.fst)) + Validate.fromPredicate(t => nt.lt(t, wn.snd), t => s"($t < ${wn.snd})", Less(wn.fst)) } object Greater { implicit def greaterValidate[T, N]( implicit - vn: AsValueOf[N, T], + wn: WitnessAs[N, T], nt: Numeric[T] ): Validate.Plain[T, Greater[N]] = - Validate.fromPredicate(t => nt.gt(t, vn.snd), t => s"($t > ${vn.snd})", Greater(vn.fst)) + Validate.fromPredicate(t => nt.gt(t, wn.snd), t => s"($t > ${wn.snd})", Greater(wn.fst)) } object Modulo { implicit def moduloValidate[T, N, O]( implicit - vn: AsValueOf[N, T], - vo: AsValueOf[O, T], + wn: WitnessAs[N, T], + wo: WitnessAs[O, T], it: Integral[T] ): Validate.Plain[T, Modulo[N, O]] = Validate.fromPredicate( - t => it.rem(t, vn.snd) == vo.snd, - t => s"($t % ${vn.snd} == ${vo.snd})", - Modulo(vn.fst, vo.fst) + t => it.rem(t, wn.snd) == wo.snd, + t => s"($t % ${wn.snd} == ${wo.snd})", + Modulo(wn.fst, wo.fst) ) } } @@ -123,8 +123,8 @@ private[refined] trait NumericInference { implicit def lessInference[C, A, B]( implicit - wa: AsValueOf[A, C], - wb: AsValueOf[B, C], + wa: WitnessAs[A, C], + wb: WitnessAs[B, C], nc: Numeric[C] ): Less[A] ==> Less[B] = Inference(nc.lt(wa.snd, wb.snd), s"lessInference(${wa.snd}, ${wb.snd})") @@ -138,8 +138,8 @@ private[refined] trait NumericInference { implicit def greaterInference[C, A, B]( implicit - wa: AsValueOf[A, C], - wb: AsValueOf[B, C], + wa: WitnessAs[A, C], + wb: WitnessAs[B, C], nc: Numeric[C] ): Greater[A] ==> Greater[B] = Inference(nc.gt(wa.snd, wb.snd), s"greaterInference(${wa.snd}, ${wb.snd})") diff --git a/modules/core/shared/src/main/scala/eu/timepit/refined/types/string.scala b/modules/core/shared/src/main/scala/eu/timepit/refined/types/string.scala index 6ffd4edea..41d9fb6f9 100644 --- a/modules/core/shared/src/main/scala/eu/timepit/refined/types/string.scala +++ b/modules/core/shared/src/main/scala/eu/timepit/refined/types/string.scala @@ -3,7 +3,7 @@ package eu.timepit.refined.types import eu.timepit.refined.W import eu.timepit.refined.api.{Refined, RefinedType, RefinedTypeOps} import eu.timepit.refined.collection.{MaxSize, NonEmpty} -import eu.timepit.refined.internal.AsValueOf +import eu.timepit.refined.internal.WitnessAs import eu.timepit.refined.string.MatchesRegex /** Module for `String` refined types. */ @@ -16,12 +16,12 @@ object string { class FiniteStringOps[N]( implicit rt: RefinedType.AuxT[FiniteString[N], String], - vn: AsValueOf[N, Int] + wn: WitnessAs[N, Int] ) extends RefinedTypeOps[FiniteString[N], String] { /** The maximum length of a `FiniteString[N]`. */ final val maxLength: Int = - vn.snd + wn.snd /** * Creates a `FiniteString[N]` from `t` by truncating it @@ -35,7 +35,7 @@ object string { def apply[N]( implicit rt: RefinedType.AuxT[FiniteString[N], String], - vn: AsValueOf[N, Int] + wn: WitnessAs[N, Int] ): FiniteStringOps[N] = new FiniteStringOps[N] } diff --git a/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala b/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala index 41240c36b..6d9157e60 100644 --- a/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala +++ b/modules/scalacheck/shared/src/main/scala/eu/timepit/refined/scalacheck/numeric.scala @@ -1,7 +1,7 @@ package eu.timepit.refined.scalacheck import eu.timepit.refined.api.{Max, Min, RefType, Validate} -import eu.timepit.refined.internal.{Adjacent, AsValueOf} +import eu.timepit.refined.internal.{Adjacent, WitnessAs} import eu.timepit.refined.numeric._ import org.scalacheck.{Arbitrary, Gen} import org.scalacheck.Gen.Choose @@ -32,60 +32,60 @@ trait NumericInstances { implicit def lessArbitrary[F[_, _]: RefType, T: Numeric: Choose: Adjacent, N]( implicit min: Min[T], - vn: AsValueOf[N, T] + wn: WitnessAs[N, T] ): Arbitrary[F[T, Less[N]]] = - rangeClosedOpenArbitrary(min.min, vn.snd) + rangeClosedOpenArbitrary(min.min, wn.snd) implicit def lessEqualArbitrary[F[_, _]: RefType, T: Numeric: Choose, N]( implicit min: Min[T], - vn: AsValueOf[N, T] + wn: WitnessAs[N, T] ): Arbitrary[F[T, LessEqual[N]]] = - rangeClosedArbitrary(min.min, vn.snd) + rangeClosedArbitrary(min.min, wn.snd) implicit def greaterArbitrary[F[_, _]: RefType, T: Numeric: Choose: Adjacent, N]( implicit max: Max[T], - vn: AsValueOf[N, T] + wn: WitnessAs[N, T] ): Arbitrary[F[T, Greater[N]]] = - rangeOpenClosedArbitrary(vn.snd, max.max) + rangeOpenClosedArbitrary(wn.snd, max.max) implicit def greaterEqualArbitrary[F[_, _]: RefType, T: Numeric: Choose, N]( implicit max: Max[T], - vn: AsValueOf[N, T] + wn: WitnessAs[N, T] ): Arbitrary[F[T, GreaterEqual[N]]] = - rangeClosedArbitrary(vn.snd, max.max) + rangeClosedArbitrary(wn.snd, max.max) /// implicit def intervalOpenArbitrary[F[_, _]: RefType, T: Numeric: Choose: Adjacent, L, H]( implicit - vl: AsValueOf[L, T], - vh: AsValueOf[H, T] + wl: WitnessAs[L, T], + wh: WitnessAs[H, T] ): Arbitrary[F[T, Interval.Open[L, H]]] = - rangeOpenArbitrary(vl.snd, vh.snd) + rangeOpenArbitrary(wl.snd, wh.snd) implicit def intervalOpenClosedArbitrary[F[_, _]: RefType, T: Numeric: Choose: Adjacent, L, H]( implicit - vl: AsValueOf[L, T], - vh: AsValueOf[H, T] + wl: WitnessAs[L, T], + wh: WitnessAs[H, T] ): Arbitrary[F[T, Interval.OpenClosed[L, H]]] = - rangeOpenClosedArbitrary(vl.snd, vh.snd) + rangeOpenClosedArbitrary(wl.snd, wh.snd) implicit def intervalClosedOpenArbitrary[F[_, _]: RefType, T: Numeric: Choose: Adjacent, L, H]( implicit - vl: AsValueOf[L, T], - vh: AsValueOf[H, T] + wl: WitnessAs[L, T], + wh: WitnessAs[H, T] ): Arbitrary[F[T, Interval.ClosedOpen[L, H]]] = - rangeClosedOpenArbitrary(vl.snd, vh.snd) + rangeClosedOpenArbitrary(wl.snd, wh.snd) implicit def intervalClosedArbitrary[F[_, _]: RefType, T: Numeric: Choose, L, H]( implicit - vl: AsValueOf[L, T], - vh: AsValueOf[H, T] + wl: WitnessAs[L, T], + wh: WitnessAs[H, T] ): Arbitrary[F[T, Interval.Closed[L, H]]] = - rangeClosedArbitrary(vl.snd, vh.snd) + rangeClosedArbitrary(wl.snd, wh.snd) /// The following functions are private because it is not guaranteed /// that they produce valid values according to the predicate `P`. diff --git a/modules/scalacheck/shared/src/test/scala/eu/timepit/refined/scalacheck/StringArbitrarySpec.scala b/modules/scalacheck/shared/src/test/scala/eu/timepit/refined/scalacheck/StringArbitrarySpec.scala index 3a7005b50..bdfa7731e 100644 --- a/modules/scalacheck/shared/src/test/scala/eu/timepit/refined/scalacheck/StringArbitrarySpec.scala +++ b/modules/scalacheck/shared/src/test/scala/eu/timepit/refined/scalacheck/StringArbitrarySpec.scala @@ -10,6 +10,7 @@ import eu.timepit.refined.scalacheck.string._ import eu.timepit.refined.string._ import eu.timepit.refined.types.string.{FiniteString, NonEmptyString} import org.scalacheck.Properties +import shapeless.nat._5 class StringArbitrarySpec extends Properties("StringArbitrary") { @@ -23,5 +24,7 @@ class StringArbitrarySpec extends Properties("StringArbitrary") { property("FiniteString[10]") = checkArbitraryRefinedType[FiniteString[W.`10`.T]] + property("FiniteString[_5]") = checkArbitraryRefinedType[FiniteString[_5]] + property("Size[Equal[8]]") = checkArbitraryRefinedType[String Refined Size[Equal[W.`8`.T]]] } From e63678f280ad0b347ad549e2eb6396d0971f3b1c Mon Sep 17 00:00:00 2001 From: "Frank S. Thomas" Date: Fri, 20 Apr 2018 22:44:24 +0200 Subject: [PATCH 11/14] Fix test failures --- build.sbt | 1 - .../eu/timepit/refined/NumericValidateSpec.scala | 12 ++++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/build.sbt b/build.sbt index c69332623..8a4728438 100644 --- a/build.sbt +++ b/build.sbt @@ -304,7 +304,6 @@ lazy val moduleCrossSettings = Def.settings( ) lazy val moduleJvmSettings = Def.settings( - fork in Test := true, mimaPreviousArtifacts := { val hasPredecessor = !unreleasedModules.value.contains(moduleName.value) latestVersionInSeries.value match { diff --git a/modules/core/shared/src/test/scala/eu/timepit/refined/NumericValidateSpec.scala b/modules/core/shared/src/test/scala/eu/timepit/refined/NumericValidateSpec.scala index a71d1b64e..1fd7cac94 100644 --- a/modules/core/shared/src/test/scala/eu/timepit/refined/NumericValidateSpec.scala +++ b/modules/core/shared/src/test/scala/eu/timepit/refined/NumericValidateSpec.scala @@ -149,7 +149,8 @@ class NumericValidateSpec extends Properties("NumericValidate") { } property("Interval.Open.showExpr") = secure { - showExpr[Interval.Open[_0, _1]](0.5) ?= "((0.5 > 0) && (0.5 < 1))" + val s = showExpr[Interval.Open[_0, _1]](0.5) + (s ?= "((0.5 > 0) && (0.5 < 1))") || (s ?= "((0.5 > 0.0) && (0.5 < 1.0))") } property("Interval.OpenClosed.isValid") = forAll { (d: Double) => @@ -157,7 +158,8 @@ class NumericValidateSpec extends Properties("NumericValidate") { } property("Interval.OpenClosed.showExpr") = secure { - showExpr[Interval.OpenClosed[_0, _1]](0.5) ?= "((0.5 > 0) && !(0.5 > 1))" + val s = showExpr[Interval.OpenClosed[_0, _1]](0.5) + (s ?= "((0.5 > 0) && !(0.5 > 1))") || (s ?= "((0.5 > 0.0) && !(0.5 > 1.0))") } property("Interval.ClosedOpen.isValid") = forAll { (d: Double) => @@ -165,7 +167,8 @@ class NumericValidateSpec extends Properties("NumericValidate") { } property("Interval.ClosedOpen.showExpr") = secure { - showExpr[Interval.ClosedOpen[_0, _1]](0.5) ?= "(!(0.5 < 0) && (0.5 < 1))" + val s = showExpr[Interval.ClosedOpen[_0, _1]](0.5) + (s ?= "(!(0.5 < 0) && (0.5 < 1))") || (s ?= "(!(0.5 < 0.0) && (0.5 < 1.0))") } property("Interval.Closed.isValid") = forAll { (d: Double) => @@ -173,6 +176,7 @@ class NumericValidateSpec extends Properties("NumericValidate") { } property("Interval.Closed.showExpr") = secure { - showExpr[Interval.Closed[_0, _1]](0.5) ?= "(!(0.5 < 0) && !(0.5 > 1))" + val s = showExpr[Interval.Closed[_0, _1]](0.5) + (s ?= "(!(0.5 < 0) && !(0.5 > 1))") || (s ?= "(!(0.5 < 0.0) && !(0.5 > 1.0))") } } From f25151d34052baa9458623234ba11dcf6beb89b0 Mon Sep 17 00:00:00 2001 From: "Frank S. Thomas" Date: Sat, 21 Apr 2018 05:47:34 +0200 Subject: [PATCH 12/14] Split validate in validate{JVM,JS} fo fix GC OOME --- .travis.yml | 6 ++++-- build.sbt | 11 +++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0e808628d..e13e3c8b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,8 @@ cache: - "$HOME/.ivy2/cache" - "$HOME/.sbt/boot/" script: -- sbt ++$TRAVIS_SCALA_VERSION validate +- sbt ++$TRAVIS_SCALA_VERSION validateJVM +- sbt ++$TRAVIS_SCALA_VERSION validateJS after_success: - codecov notifications: @@ -31,7 +32,8 @@ matrix: before_install: - curl https://raw.githubusercontent.com/scala-native/scala-native/master/scripts/travis_setup.sh | bash -x script: - - sbt ++$TRAVIS_SCALA_VERSION compileNative validate + - sbt ++$TRAVIS_SCALA_VERSION compileNative validateJVM + - sbt ++$TRAVIS_SCALA_VERSION validateJS - scala: 2.13.0-M3 # Remember to update this in build.sbt, too. script: - sbt ++$TRAVIS_SCALA_VERSION coreJVM/compile diff --git a/build.sbt b/build.sbt index 8a4728438..0d3bfaf48 100644 --- a/build.sbt +++ b/build.sbt @@ -481,7 +481,7 @@ addCommandsAlias("testJS", allSubprojectsJS.map(_ + "/test")) addCommandsAlias("testJVM", allSubprojectsJVM.map(_ + "/test")) addCommandsAlias( - "validate", + "validateJVM", Seq( "clean", "scalafmtCheck", @@ -490,7 +490,6 @@ addCommandsAlias( "scalastyle", "test:scalastyle", "mimaReportBinaryIssues", - "testJS", "coverage", "testJVM", "coverageReport", @@ -501,3 +500,11 @@ addCommandsAlias( "packageSrc" ) ) + +addCommandsAlias( + "validateJS", + Seq( + "clean", + "testJS" + ) +) From cae5bc5125491cb6d441beccd3db8675ba1fc823 Mon Sep 17 00:00:00 2001 From: "Frank S. Thomas" Date: Sat, 21 Apr 2018 06:01:00 +0200 Subject: [PATCH 13/14] Do not clean again in validateJS --- build.sbt | 1 - 1 file changed, 1 deletion(-) diff --git a/build.sbt b/build.sbt index 0d3bfaf48..9db968874 100644 --- a/build.sbt +++ b/build.sbt @@ -504,7 +504,6 @@ addCommandsAlias( addCommandsAlias( "validateJS", Seq( - "clean", "testJS" ) ) From 4443b368d0fa1af234c6d558b7f8477172e99337 Mon Sep 17 00:00:00 2001 From: "Frank S. Thomas" Date: Sat, 21 Apr 2018 06:16:52 +0200 Subject: [PATCH 14/14] Update release notes --- notes/0.9.0.markdown | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/notes/0.9.0.markdown b/notes/0.9.0.markdown index 29cfa5321..5149e0dc0 100644 --- a/notes/0.9.0.markdown +++ b/notes/0.9.0.markdown @@ -37,6 +37,11 @@ [scala-dev/#446][scala-dev/#446]. ([#438][#438]) * Update documentation to solve "exception during macro expansion" errors. ([#451][#451] by [@umbreak][@umbreak]) +* Change the definition of `MaxSize[N]` from `Size[LessEqual[N]]` to + `Size[Interval.Closed[_0, N]]` and introduce the `WitnessAs` type class + which unifies numeric type class instances that were split to work with + literal singleton types and `shapeless.Nat`. + ([#473][#473], [#483][#483]) ### Deprecations and removals @@ -87,10 +92,12 @@ [#467]: https://github.com/fthomas/refined/pull/467 [#468]: https://github.com/fthomas/refined/pull/468 [#471]: https://github.com/fthomas/refined/pull/471 +[#473]: https://github.com/fthomas/refined/issues/473 [#475]: https://github.com/fthomas/refined/pull/475 [#478]: https://github.com/fthomas/refined/pull/478 [#479]: https://github.com/fthomas/refined/pull/479 [#482]: https://github.com/fthomas/refined/pull/482 +[#483]: https://github.com/fthomas/refined/pull/483 [scala-dev/#446]: https://github.com/scala/scala-dev/issues/446 [@densh]: https://github.com/densh