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

Draft macroless ==> #758

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ val jsonpathVersion = "2.4.0"
val macroParadiseVersion = "2.1.1"
val pureconfigVersion = "0.12.3"
val shapelessVersion = "2.3.3"
val singletonopsVersion = "0.5.0+7-ca9541e6-SNAPSHOT"
val scalaCheckVersion = "1.14.3"
val scalaXmlVersion = "1.3.0"
val scalazVersion = "7.2.28"
Expand Down Expand Up @@ -126,6 +127,7 @@ lazy val core = myCrossProject("core")
scalaOrganization.value % "scala-compiler" % scalaVersion.value,
"com.chuusai" %%% "shapeless" % shapelessVersion,
"org.scala-lang.modules" %% "scala-xml" % scalaXmlVersion,
"eu.timepit" %% "singleton-ops" % singletonopsVersion,
scalaCheckDep.value % Test
),
initialCommands += s"""
Expand Down Expand Up @@ -450,7 +452,7 @@ addCommandsAlias(
"fmt",
Seq(
"scalafmt",
"test:scalafmt",
//"test:scalafmt",
"scalafmtSbt"
)
)
Expand All @@ -459,7 +461,7 @@ addCommandsAlias(
"fmtCheck",
Seq(
"scalafmtCheck",
"test:scalafmtCheck",
//"test:scalafmtCheck",
"scalafmtSbtCheck",
"scalastyle",
"test:scalastyle"
Expand Down
11 changes: 0 additions & 11 deletions latestVersion.sbt
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
latestVersion in ThisBuild := "0.9.14"

bincompatVersions in ThisBuild := Set(
"0.9.3",
"0.9.4",
"0.9.5",
"0.9.6",
"0.9.7",
"0.9.8",
"0.9.9",
"0.9.10",
"0.9.12",
"0.9.13",
"0.9.14"
// NEXT_VERSION
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ package eu.timepit.refined.api
* `Inference[P, C]` exists, the type `F[T, P]` is considered a subtype
* of `F[T, C]`.
*/
case class Inference[P, C](isValid: Boolean, show: String) {
case class Inference[P, C](show: String) {

final def adapt[P2, C2](adaptedShow: String): Inference[P2, C2] =
copy(show = adaptedShow.format(show))

final def notValid: Boolean =
!isValid
}

object Inference {
Expand All @@ -24,12 +22,12 @@ object Inference {
def apply[P, C](implicit i: Inference[P, C]): Inference[P, C] = i

def alwaysValid[P, C](show: String): Inference[P, C] =
Inference(isValid = true, show)
Inference(show)

def combine[P1, P2, P, C1, C2, C](
i1: Inference[P1, C1],
i2: Inference[P2, C2],
show: String
): Inference[P, C] =
Inference(i1.isValid && i2.isValid, show.format(i1.show, i2.show))
Inference(show.format(i1.show, i2.show))
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package eu.timepit.refined

import eu.timepit.refined.api.{Refined, RefType, Validate}
import eu.timepit.refined.api.Inference.==>
import eu.timepit.refined.macros.{InferMacro, RefineMacro}
import eu.timepit.refined.macros.RefineMacro
import shapeless.tag.@@

/**
Expand Down Expand Up @@ -30,7 +30,8 @@ object auto {
implicit def autoInfer[F[_, _], T, A, B](ta: F[T, A])(
implicit rt: RefType[F],
ir: A ==> B
): F[T, B] = macro InferMacro.impl[F, T, A, B]
): F[T, B] =
rt.unsafeRewrap[T, A, B](ta)

/**
* Implicitly unwraps the `T` from a value of type `F[T, P]` using the
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
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.api.Validate
import eu.timepit.refined.internal.WitnessAs
import shapeless._
import shapeless.ops.coproduct.ToHList
import shapeless.ops.hlist.ToList
import shapeless.ops.record.Keys

/** Module for generic predicates. */
object generic extends GenericInference {
object generic {

/** Predicate that checks if a value is equal to `U`. */
final case class Equal[U](u: U)
Expand Down Expand Up @@ -101,13 +99,3 @@ object generic extends GenericInference {
Validate.alwaysPassed(Supertype())
}
}

private[refined] trait GenericInference {

implicit def equalValidateInference[T, U, P](
implicit
v: Validate[T, P],
wu: WitnessAs[U, T]
): Equal[U] ==> P =
Inference(v.isValid(wu.snd), s"equalValidateInference(${v.showExpr(wu.snd)})")
}

This file was deleted.

43 changes: 15 additions & 28 deletions modules/core/shared/src/main/scala/eu/timepit/refined/numeric.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import eu.timepit.refined.api.Inference.==>
import eu.timepit.refined.boolean.{And, Not}
import eu.timepit.refined.internal.WitnessAs
import eu.timepit.refined.numeric._
import shapeless.Nat
//import shapeless.Nat
import shapeless.nat.{_0, _2}
import shapeless.ops.nat.ToInt
//import shapeless.ops.nat.ToInt
import singleton.ops.{<, >, Id, OpAuxBoolean}

/**
* Module for numeric predicates. Predicates that take type parameters
Expand Down Expand Up @@ -132,39 +133,25 @@ object numeric extends NumericInference {

private[refined] trait NumericInference {

implicit def lessInference[C, A, B](
implicit def lessInference[A, B](
implicit
wa: WitnessAs[A, C],
wb: WitnessAs[B, C],
nc: Numeric[C]
t: OpAuxBoolean[A < B, W.`true`.T],
va: Id[A],
vb: Id[B]
): Less[A] ==> Less[B] =
Inference(nc.lt(wa.snd, wb.snd), s"lessInference(${wa.snd}, ${wb.snd})")
Inference(s"lessInference(${va.value}, ${vb.value})")

implicit def lessInferenceNat[A <: Nat, B <: Nat](
implicit def greaterInference[A, B](
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: 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})")

implicit def greaterInferenceNat[A <: Nat, B <: Nat](
implicit
ta: ToInt[A],
tb: ToInt[B]
t: OpAuxBoolean[A > B, W.`true`.T],
va: Id[A],
vb: Id[B]
): Greater[A] ==> Greater[B] =
Inference(ta() > tb(), s"greaterInferenceNat(${ta()}, ${tb()})")
Inference(s"greaterInference(${va.value}, ${vb.value})")

implicit def greaterEqualInference[A]: Greater[A] ==> GreaterEqual[A] =
Inference.alwaysValid("greaterEqualInference")
Inference("greaterEqualInference")

implicit def lessEqualInference[A]: Less[A] ==> LessEqual[A] =
Inference.alwaysValid("lessEqualInference")
Inference("lessEqualInference")
}
21 changes: 13 additions & 8 deletions modules/core/shared/src/main/scala/eu/timepit/refined/string.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import eu.timepit.refined.api.{Inference, Validate}
import eu.timepit.refined.api.Inference.==>
import eu.timepit.refined.string._
import shapeless.Witness
import singleton.ops.{EndsWith => EW, Id, OpAuxBoolean, StartsWith => SW}

/**
* Module for `String` related predicates. Note that most of the predicates
Expand Down Expand Up @@ -252,15 +253,19 @@ object string extends StringInference {

private[refined] trait StringInference {

implicit def endsWithInference[A <: String, B <: String](
implicit wa: Witness.Aux[A],
wb: Witness.Aux[B]
implicit def endsWithInference[A, B](
implicit
t: OpAuxBoolean[EW[A, B], W.`true`.T],
va: Id[A],
vb: Id[B]
): EndsWith[A] ==> EndsWith[B] =
Inference(wa.value.endsWith(wb.value), s"endsWithInference(${wa.value}, ${wb.value})")
Inference(s"endsWithInference(${va.value}, ${vb.value})")

implicit def startsWithInference[A <: String, B <: String](
implicit wa: Witness.Aux[A],
wb: Witness.Aux[B]
implicit def startsWithInference[A, B](
implicit
t: OpAuxBoolean[SW[A, B], W.`true`.T],
va: Id[A],
vb: Id[B]
): StartsWith[A] ==> StartsWith[B] =
Inference(wa.value.startsWith(wb.value), s"startsWithInference(${wa.value}, ${wb.value})")
Inference(s"startsWithInference(${va.value}, ${vb.value})")
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ import shapeless.tag.@@
import shapeless.test.illTyped

class AutoSpec extends Properties("auto") {

property("autoInfer") = secure {
val a: Char Refined Equal[W.`'0'`.T] = '0'
val b: Char Refined Digit = a
val b: Char Refined Digit = '0'
illTyped(
"val c: Char Refined Letter = a",
"""type mismatch \(invalid inference\):\s*eu.timepit.refined.generic.Equal\[Char\('0'\)\] does not imply\s*eu.timepit.refined.char.Letter"""
"""type mismatch.*"""
)
a == b
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package eu.timepit.refined

import eu.timepit.refined.TestUtils.wellTyped
import eu.timepit.refined.api.Inference
//import eu.timepit.refined.api.Inference
import eu.timepit.refined.boolean._
import eu.timepit.refined.char.{Digit, Letter, UpperCase, Whitespace}
import eu.timepit.refined.numeric._
Expand All @@ -11,10 +11,11 @@ import shapeless.nat._
import shapeless.test.illTyped

class BooleanInferenceSpec extends Properties("BooleanInference") {
import shim.Inference

property("double negation elimination with Greater") = secure {
Inference[Not[Not[Greater[_5]]], Greater[_4]] ?=
Inference(5 > 4, "doubleNegationElimination(greaterInferenceNat(5, 4))")
eu.timepit.refined.api.Inference[Not[Not[Greater[_5]]], Greater[_4]] ?=
eu.timepit.refined.api.Inference("doubleNegationElimination(greaterInference(5, 4))")
}

property("double negation elimination") = secure {
Expand Down Expand Up @@ -64,7 +65,10 @@ class BooleanInferenceSpec extends Properties("BooleanInference") {
}

property("conjunction introduction") = wellTyped {
illTyped("Inference[UpperCase, UpperCase And Digit]", "could not find.*Inference.*")
illTyped(
"eu.timepit.refined.api.Inference[UpperCase, UpperCase And Digit]",
"could not find.*Inference.*"
)
}

property("disjunction associativity") = secure {
Expand All @@ -84,7 +88,10 @@ class BooleanInferenceSpec extends Properties("BooleanInference") {
}

property("disjunction elimination") = wellTyped {
illTyped("Inference[UpperCase Or Digit, Digit]", "could not find.*Inference.*")
illTyped(
"eu.timepit.refined.api.Inference[UpperCase Or Digit, Digit]",
"could not find.*Inference.*"
)
}

property("De Morgan's law 1") = secure {
Expand Down Expand Up @@ -144,7 +151,7 @@ class BooleanInferenceSpec extends Properties("BooleanInference") {
}

property("modus tollens") = secure {
Inference[Not[Digit Xor Letter], Not[Letter Xor Digit]] ?=
Inference.alwaysValid("modusTollens(xorCommutativity)")
eu.timepit.refined.api.Inference[Not[Digit Xor Letter], Not[Letter Xor Digit]] ?=
eu.timepit.refined.api.Inference("modusTollens(xorCommutativity)")
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package eu.timepit.refined

import eu.timepit.refined.TestUtils.wellTyped
import eu.timepit.refined.api.Inference
//import eu.timepit.refined.api.Inference
import eu.timepit.refined.char._
import eu.timepit.refined.collection._
import eu.timepit.refined.numeric.Greater
Expand All @@ -11,17 +11,22 @@ import shapeless.nat._
import shapeless.test.illTyped

class CollectionInferenceSpec extends Properties("CollectionInference") {
import shim.Inference

/*
property("Exists[A] ==> Exists[B]") = secure {
Inference[Contains[W.`'5'`.T], Exists[Digit]].isValid
}

*/
property("Exists ==> NonEmpty") = secure {
Inference[Exists[Digit], NonEmpty].isValid
}

property("NonEmpty =!> Exists") = wellTyped {
illTyped("Inference[NonEmpty, Exists[Digit]]", "could not find.*Inference.*")
illTyped(
"eu.timepit.refined.api.Inference[NonEmpty, Exists[Digit]]",
"could not find.*Inference.*"
)
}

property("Head[A] ==> Head[B]") = secure {
Expand All @@ -33,7 +38,7 @@ class CollectionInferenceSpec extends Properties("CollectionInference") {
}

property("Exists[A] =!> Head[A]") = wellTyped {
illTyped("Inference[Exists[Digit], Head[Digit]]")
illTyped("eu.timepit.refined.api.Inference[Exists[Digit], Head[Digit]]")
}

property("Index[N, A] ==> Index[N, B]") = secure {
Expand All @@ -57,7 +62,10 @@ class CollectionInferenceSpec extends Properties("CollectionInference") {
}

property("NonEmpty =!> Last") = wellTyped {
illTyped("Inference[NonEmpty, Last[Whitespace]]", "could not find.*Inference.*")
illTyped(
"eu.timepit.refined.api.Inference[NonEmpty, Last[Whitespace]]",
"could not find.*Inference.*"
)
}

property("Size[A] ==> Size[B]") = secure {
Expand Down
Loading