Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Oct 21 18:16
    mebubo starred fthomas/refined
  • Oct 20 17:59
    kshaa starred fthomas/refined
  • Oct 19 23:30

    mergify[bot] on master

    Update sbt to 1.4.1 Merge pull request #860 from sc… (compare)

  • Oct 19 23:30
    mergify[bot] closed #860
  • Oct 19 23:30
    codecov[bot] commented #860
  • Oct 19 23:29
    codecov[bot] commented #860
  • Oct 19 23:20
    mergify[bot] labeled #860
  • Oct 19 23:20
    mergify[bot] assigned #860
  • Oct 19 23:19
    scala-steward opened #860
  • Oct 19 19:00

    mergify[bot] on master

    Update sbt-mima-plugin to 0.8.1 Merge pull request #859 from sc… (compare)

  • Oct 19 19:00
    mergify[bot] closed #859
  • Oct 19 19:00
    codecov[bot] commented #859
  • Oct 19 18:59
    codecov[bot] commented #859
  • Oct 19 18:51
    mergify[bot] labeled #859
  • Oct 19 18:51
    mergify[bot] assigned #859
  • Oct 19 18:50
    scala-steward opened #859
  • Oct 19 07:48
    Travis wegtam/refined (master) fixed (219)
  • Oct 18 16:33

    mergify[bot] on master

    Update sbt-dotty to 0.4.4 Merge pull request #858 from sc… (compare)

  • Oct 18 16:33
    mergify[bot] closed #858
  • Oct 18 16:32
    codecov[bot] commented #858
Frank S. Thomas
@fthomas
@gordon-rennie Unfortunately not. There are no BigDecimal literals in Scala.
Jens Grassel
@jan0sch

Hi, I was wondering if one could re-use the already provided scalacheck generators of refined within own generators. So instead of having something like

forAll(...) { (a: A, b: B, c: C) =>
  val myStuff = Stuff(a, b, c)
  // ...
}

one could write

val genStuff: Gen[Stuff] = for {
  a <- ???
  b <- ???
  c <- ???
} yield Stuff(a, b, c)

Has someone already done so?

8 replies
David Zhu
@noblecraft
This message was deleted
Jens Grassel
@jan0sch

Hi, I've got a problem with pureconfig (0.13.0) after upgrading to refined 0.9.15.

In a config I have a field which is a Array[Byte] at runtime and use a custom converter like this:

type CookieSecret = Array[Byte] Refined NonEmpty

implicit val reader: ConfigReader[CookieSecret] =
  ConfigReader[String].emap(s =>
    CookieSecret
      .from(s.getBytes(StandardCharsets.UTF_8))
      .leftMap(e => CannotConvert(s, "CookieSecret", e))
  )

The entry is stored as a String in the configuration file, so it has to be converted when read. However since the upgrade I get an error about ambiguous implicit values.

[error] .../ServiceConfig.scala:58:16: ambiguous implicit values:
[error]  both method refTypeConfigConvert in package pureconfig of type [F[_, _], T, P](implicit configConvert: pureconfig.ConfigConvert[T], refType: eu.timepit.refined.api.RefType[F], validate: eu.timepit.refined.api.Validate[T,P], typeTag: reflect.runtime.universe.WeakTypeTag[F[T,P]]): pureconfig.ConfigConvert[F[T,P]]
[error]  and value reader in object ServiceConfig of type pureconfig.ConfigReader[CookieSecret]
[error]  match expected type pureconfig.ConfigReader[eu.timepit.refined.api.Refined[Array[Byte],eu.timepit.refined.boolean.Not[eu.timepit.refined.collection.Empty]]]

Is there a simple way to override the implicit provided by refined?
For a simple config I already removed the eu.timepit.refined.pureconfig._ import and wrote the 2-3 readers by hand. But here we're talking about a bigger one which I would like to have derived if possible.

Jente Hidskes
@Hjdskes

I need some help figuring out what seems to be an issue with an Inference instance. In short, we have a NonEmptyFiniteString[35] that we try to assign to a value of type NonEmptyFiniteString[50] which Refined cannot infer is always valid.

In trying to figure this out, I took the expanded predicate of NonEmptyFiniteString[N], which is Size[And[Not[Less[1]], Not[Greater[N]]]] and worked my way up from the primitives:

{
  val s: Int Refined Not[Less[2]] = 3
  val ss: Int Refined Not[Less[1]] = s
}

{
  val s: Int Refined Not[Greater[35]] = 4
  val ss: Int Refined Not[Greater[50]] = s
}

{
  val s: Int Refined And[Not[Less[1]], Not[Greater[35]]] = 16
  val ss: Int Refined And[Not[Less[1]], Not[Greater[50]]] = s
}

This last one breaks, but I'm stuck figuring out why. Can someone help? :)

Jente Hidskes
@Hjdskes

I believe there is an inference rule missing for (A And B) ==> (C And D) but I wouldn't immediately know what a valid instance for that would look like. Intuitively, it would seem to be

implicit def andInference[A, B, C, D](implicit ac: A ==> C, bd: B ==> D): And[A, B] ==> And[C, D] =
  Inference.combine(ac, bd, "and")

but that's incorrect.

In any case, adding this instance to my scratchpad does solve my problem.
Jente Hidskes
@Hjdskes
On second thought, that inference rule might be correct after all. What do you think @fthomas ?
wpoosanguansit
@wpoosanguansit
hi, I am trying to use Refined with Shapeless @@ type. Something along the line of NonEmptyString @@ "MyType". It seems to compile fine. But how do I reify string to this type? is there an example or if there is a better way to refine NonEmptyString with custom type? I appreciate your help.
Jente Hidskes
@Hjdskes
@wpoosanguansit Have you seen https://github.com/estatico/scala-newtype?
wpoosanguansit
@wpoosanguansit
@Hjdskes thanks. I have not seen that in Scala before. My use case is just to differentiate on a bunch of strings that I have. I am just not sure yet how to reify string into NonEmptyString @@ "MyType" for example.
wpoosanguansit
@wpoosanguansit

I hope somebody can point me to where I should look for this. Basically, I like to have this:

type Object1              = NonEmptyString @@ "Object1"
  object Object1 extends RefinedTypeOps[Object1, String] with CatsRefinedTypeOpsSyntax

But this would error out with - could not find implicit value for parameter rt: eu.timepit.refined.api.RefinedType.AuxT[Object1, String]

how should I resolve this? Appreciate your help.

Lawrence Wagerfield
@ljwagerfield
Can refined be used to express multivariate inequalities like x < y in case class Foo(x: Int, y: Int)?
Dmytro Mitin
@DmytroMitin
@ljwagerfield It's better to use https://github.com/fthomas/singleton-ops for that
import singleton.ops._
case class Foo[N <: Int with Singleton, M <: Int with Singleton](x: N, y: M)(implicit ev: Require[N < M])
Foo(1, 2) // compiles
// Foo(2, 1) // doesn't compile
Lawrence Wagerfield
@ljwagerfield
nice, thanks!
Julien Richard-Foy
@julienrf
Hello, I’m sorry if this has been asked already but I couldn’t find the info. Let’s say that I’m writing a method def abs(x: Int): Refined[Int, Positive]. How should I implement it?
Am I supposed to call unsafeFrom?
Frank S. Thomas
@fthomas
@julienrf It depends on what you want to happen if the parameter does not conform to the predicate. unsafeFrom will throw at runtime, refineV or PosInt.from returns a Left in case of an error, and then there is also Refined.unsafeApply which does not check the parameter at all. Btw, for abs you probably want to use NonNegInt or the NonNeg predicate which also allows 0
Julien Richard-Foy
@julienrf
@fthomas good point about NonNeg :) Well, the result does conform to the predicate (my goal is to guarantee that my API produces a refined value), so most probably I should use unsafeFrom.
Frank S. Thomas
@fthomas
Ah right, you're always producing a refined value, so using unsafeFrom is fine. In the library we're using Refined.unsafeApply for similar cases (e.g. FiniteString.truncate) to not incur the runtime check that our value conforms to the predicate.
Saqib Saleem
@trywe-ltd

Hi. I have just started to look at pureconfig and refined but I have run in to some problems so any guidance would be greatly appreciated.
I have the following application.conf:

server {
  name = "test"
  host = "127.0.0.1"
  port = "8990"
}

and this build.sbt:

lazy val pureconfig = (project in file("pureconfig"))
  .settings(
    libraryDependencies ++= Seq(
      "com.github.pureconfig" %% "pureconfig" % "0.13.0",
      "eu.timepit" %% "refined-cats" % "0.9.15",
      "eu.timepit" %% "refined-pureconfig" % "0.9.15"
    ),
    scalacOptions += "-Ymacro-annotations"
  )

I have a single Main object that looks like this:

import eu.timepit.refined.api.Refined
import eu.timepit.refined.string.IPv4
import eu.timepit.refined.types.net.UserPortNumber
import pureconfig._
import eu.timepit.refined.pureconfig._
import eu.timepit.refined.auto._
import eu.timepit.refined.numeric._
import pureconfig.generic.auto._

object Main extends App {
  type Host = String Refined IPv4
  type Port = String Refined UserPortNumber

  final case class Server(name: String, host: String, port: Port)

  private val config = ConfigSource.default.load[Server].fold(
    failed => throw new IllegalStateException("Could not load config"),
    config => config
  )

  println(s"AppConfig: ${config.toString}")
}

When I try to compile I get the following error:
[error] /scala/playground/pureconfig/src/main/scala/Main.scala:17:49: Cannot find an implicit instance of pureconfig.ConfigReader[Main.Server]. [error] If you are trying to read or write a case class or sealed trait consider using PureConfig's auto derivation by adding `import pureconfig.generic.auto._` [error] private val config = ConfigSource.default.load[Server].fold(

I am doing something incorrect here but what? Thanks in advance!

wpoosanguansit
@wpoosanguansit
hi, I hope you do not mind a newbie question. what do we usually need to define when we have "could not find implicit value for parameter rt: eu.timepit.refined.api.RefinedType.AuxT[Custom, String]"? I do run into this when I am trying to use And or Or in the types for String. thanks for your help.
Melvic Ybanez
@melvic-ybanez
Hi @fthomas I couldn't make the following regex work: MatchesRegex[W."""(0|+44)([0-9]{10})""".T]. It says invalid escape character at \+. Am I missing something?
Melvic Ybanez
@melvic-ybanez
If I tried to use the single quoted literal, MatchesRegex[W."(0|\+44)([0-9]{10})".T], I got malformed literal.
Thanks in advance
Melvic Ybanez
@melvic-ybanez
I also tried double slashes for the single-quoted literal, btw. still malformed
Frank S. Thomas
@fthomas
@melvic-ybanez W.`"""\\+"""`.T or W.`"\\\\+"`.T works
Melvic Ybanez
@melvic-ybanez
@fthomas sorry, I just realized some of the characters are lost when I pasted the code here. But yes, adding additional back slash character even in triple quotes works.
Thanks
Andrii Kondiuk
@andriikondiuk_gitlab
Hi All, I was wondering is there are integration Refined with Finagle?
I've found finch-refined module, but I can't find a finagle-refind, thanks
Frank S. Thomas
@fthomas
@andriikondiuk_gitlab I'm not aware of a finagle-refined module
Andrii Kondiuk
@andriikondiuk_gitlab
@fthomas thank you
Billzabob
@Billzabob
Why would I be getting this error? Am I doing something dumb?
[error]  found   : Int(10)
[error]  required: fs2.aws.s3.PartSizeMB
[error]     (which expands to)  eu.timepit.refined.api.Refined[Int,eu.timepit.refined.boolean.Or[eu.timepit.refined.numeric.Greater[Int(5)],eu.timepit.refined.generic.Equal[Int(5)]]]
[error]     val foo: PartSizeMB = 10
Jente Hidskes
@Hjdskes
Do you have import eu.timepit.refined.auto._?
Billzabob
@Billzabob
Nope, that fixed it :) Thanks!
michealhill
@micheal-hill
Is there anything I can do to allow numeric types to be widened? For example, I'd like to make a situation like this work:
val a: Int Refined Greater[10] = 20
val b: Int Refined Greater[5] = a
Frank S. Thomas
@fthomas
@micheal-hill Try import eu.timepit.refined.auto._
michealhill
@micheal-hill
complete snippet is actually:
import eu.timepit.refined.api.Refined
import eu.timepit.refined.numeric._
import eu.timepit.refined.auto._
val a: Int Refined Greater[10] = 20
val b: Int Refined Greater[5] = a
ah.. I think it does actually work; the IDE is just lying
sorry!
Julien Richard-Foy
@julienrf

Hello, I’m sorry if this has already been asked, but I would like to support the following syntax:

case class PosSeconds(n: PosInt)

val posSeconds = 3.seconds // : PosSeconds = PosSeconds(3)

I’ve tried to create an implicit conversion from Int, but I couldn’t figure out which implicit evidence I could take as a parameter to prove that my Int parameter is indeed Positive:

class RichPosInt(n: PosInt) {
  def seconds: PosSeconds = PosSeconds(n)
}

implicit def RichPosInt(n: Int)(implicit r: Refined[n.type, Positive]): RichPosInt = RichPosInt(n)

But the code fails to compile with the following error: “compile-time refinement only works with literals”

Frank S. Thomas
@fthomas
@julienrf Does implicit def RichPosInt(n: PosInt): RichPosInt = RichPosInt(n) work? The implicit macro imported via eu.timepit.refined.auto._ converts the Int to PosInt and def RichPosInt would then allow using the seconds extension
Stanislav Kovalenko
@PepRoll
Hello, I've tried to refine my enumeratum class, when I tried to use the object of my enum as a literal I saw this error "compile-time refinement only works with literals". Can I use an object as literal?
Julien Richard-Foy
@julienrf
@fthomas No, unfortunately it doesn’t work because this would require the application of two implicit conversions in a row (the refined.auto one, and the RichPosInt one)
Dmytro Mitin
@DmytroMitin
@julienrf You can chain implicit conversions https://docs.scala-lang.org/tutorials/FAQ/chaining-implicits.html
Oron Port
@soronpo
@julienrf you can use singleton-ops the same way coulomb does https://github.com/erikerlandson/coulomb
Dmytro Mitin
@DmytroMitin

@julienrf Refined is not a type class, so implicit r: Refined[...]can't be correct.

implicit def RichPosInt(n: Int)(implicit r: Int => PosInt): RichPosInt = new RichPosInt(n)

could have better chances to work but it doesn't. If you resolve implicits manually

RichPosInt(3)(eu.timepit.refined.auto.autoRefineV(_)).seconds

you'll see compile-time refinement only works with literals. The thing is that implicit conversions brought by import eu.timepit.refined.auto._ are not type-based (implicit ev: A => B not always checks that there is an implicit conversion from A to B, see 1 2 3 4 5) but implemented as macros and work with literals only. So the only way I can see to make your implicit conversion RichPosInt work is to make it macro-based as well. This postpones expansion of autoRefineV till when n is actually a literal.

object RichPosIntImplicits {
  implicit def RichPosInt(n: Int): RichPosInt = macro RichPosIntImpl
  def RichPosIntImpl(c: blackbox.Context)(n: c.Tree): c.Tree = {
    import c.universe._
    q"new RichPosInt(_root_.eu.timepit.refined.auto.autoRefineV($n))"
  }
}

import RichPosIntImplicits._
3.seconds // compiles
Julien Richard-Foy
@julienrf
@DmytroMitin I understand, thanks a lot!
Billzabob
@Billzabob
Is there an easy way to append a String to a NonEmptyString and get a NonEmptyString back? Or do I just need to use the unsafe methods?