Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Oct 14 18:09
    manfredi-giordano starred fthomas/refined
  • Oct 14 16:16
    codecov[bot] commented #692
  • Oct 14 16:14

    mergify[bot] on master

    Update sbt to 1.3.3 Merge pull request #692 from sc… (compare)

  • Oct 14 16:14
    mergify[bot] closed #692
  • Oct 14 16:14
    codecov[bot] commented #692
  • Oct 14 16:10
  • Oct 14 15:53
    scala-steward opened #693
  • Oct 14 15:53
    scala-steward opened #692
  • Oct 14 05:06

    fthomas on master

    Do not use deprecated Symbol sy… (compare)

  • Oct 14 05:06
    fthomas closed #691
  • Oct 14 04:59
    codecov[bot] commented #691
  • Oct 14 04:58
    codecov[bot] commented #691
  • Oct 14 04:57
    codecov[bot] commented #691
  • Oct 14 04:55
    Travis fthomas/refined (topic/no-symbol-syntax) fixed (3401)
  • Oct 14 04:36
    fthomas synchronize #691
  • Oct 14 04:36

    fthomas on no-symbol-syntax

    Fix deprecation (compare)

  • Oct 13 20:42
  • Oct 13 20:35
    Travis fthomas/refined (topic/no-symbol-syntax) still failing (3399)
  • Oct 13 20:24
    fthomas synchronize #691
  • Oct 13 20:24

    fthomas on no-symbol-syntax

    Fix error method createPropert… (compare)

Rafael Saraiva Figueiredo
@saraiva132
Is there anything I need to import or provide ? So that the type can be properly inferred
Frank S. Thomas
@fthomas
Is that IntelliJ or the Scala compiler reporting that type? Instead of Any, the type should be UserPortNumber, no additional imports are required.
Rafael Saraiva Figueiredo
@saraiva132
Yes, it is IntelliJ issue apparently, that is a bit disappointing :(
Rafael Saraiva Figueiredo
@saraiva132
Any advice for me to solve this? Move to metals ? xd
Frank S. Thomas
@fthomas
Get used to it. :-) I hope the situation will improve soon because literal types are an official feature of Scala 2.13
Rafael Saraiva Figueiredo
@saraiva132
Yeah, I have seen the open PR. I will wait :)
Jens Grassel
@jan0sch
Hi, I'm currently playing with tapir (https://github.com/softwaremill/tapir) and wonder if there is a way to extract "format" information from refined types to use it in the OpenAPI docs.
Has anyone an idea?
Frank S. Thomas
@fthomas
@jan0sch Is there some type class in Tapir for extracting "format" information? How does this works for other types?
Jens Grassel
@jan0sch
@fthomas They have some SchemaFor / Schema stuff going on. I've not dug that deep but it seems they use magnolia.
There is also circe integration so maybe something from circe-refined could be used? But maybe I'm totally wrong. ;-)
Frank S. Thomas
@fthomas
@jan0sch It seems that SchemaFor basically provides a String for a type. So if you want the schema to be "int" for Int Refined Positive for example, this would be easy. If it should be "positive int", I think you'll need to write a SchemaFor instance for the Positive predicate.
Jens Grassel
@jan0sch
Ok, thanks for the info. Would there be a way to make such things "deriveable" by providing some helpers?
But I guess this question is better for the tapir channel. :thought_balloon:
Frank S. Thomas
@fthomas
I guess at some point you have to write out what the string representation (schema) for each predicate should be.
Jens Grassel
@jan0sch
Yes, did a look at the source and it seems that would be the way to go. Is there a way to get the regular expression which is used by a refined String?
That would be cool to generate more information which could be reflected in the OpenAPI description (e.g. "type = string" and "format = regex").
Frank S. Thomas
@fthomas
If you mean the regex in String Refined MatchesRegex[regex], then yes, is possible to get the value of regex out of this type
Jens Grassel
@jan0sch
Cool, how would this work? Something like MyType.whatever?
Frank S. Thomas
@fthomas
It can be done via an implicit Witness, similar to how the Validate instances for MatchesRegex is defined
Jens Grassel
@jan0sch
Ah, merci. :-)
Isaias Bartelborth
@isaias-b

I have a small question regarding Gen instances for scalacheck. I found this to work to automatically derive Arbitrary instances:

import eu.timepit.refined.W
import eu.timepit.refined.api.Refined
import eu.timepit.refined.numeric.Interval
type SomeInterval = Int Refined Interval.Closed[W.`0`.T, W.`xFFFE`.T]

object Arbs {
  import eu.timepit.refined.api.RefType._
  import eu.timepit.refined.scalacheck.all._
  import org.scalacheck.Arbitrary
  implicit val arbSomeInterval: Arbitrary[SomeInterval] = implicitly[Arbitrary[SomeInterval]]
}

However i have the need to compose some of the generators for my refined types. So i was looking for something that could generate that same generator being used within the Arbitrary instance of that implicit resolution of implicitly[Arbitrary[SomeInterval]]. This is what i came up with by copying the code from the library module and renaming the members:

  object Arbs2 {
    import eu.timepit.refined.api.RefType
    import eu.timepit.refined.internal.WitnessAs
    import org.scalacheck.Gen.Choose
    import org.scalacheck.{Arbitrary, Gen}

    implicit def intervalClosedArbitrary2[F[_, _]: RefType, T: Numeric: Choose, L, H](
      implicit
      wl: WitnessAs[L, T],
      wh: WitnessAs[H, T]
    ): Arbitrary[F[T, Interval.Closed[L, H]]] = rangeClosedArbitrary2(wl.snd, wh.snd)
    private def rangeClosedArbitrary2[F[_, _]: RefType, T: Numeric: Choose, P](
      min: T,
      max: T
    ): Arbitrary[F[T, P]] = arbitraryRefType2(Gen.chooseNum(min, max))

    def arbitraryRefType2[F[_, _], T, P](gen: Gen[T])(
      implicit rt: RefType[F]
    ): Arbitrary[F[T, P]] = Arbitrary(gen.map(rt.unsafeWrap))

    implicit val arb2SomeInterval: Arbitrary[SomeInterval] = implicitly[Arbitrary[SomeInterval]]
  }

So this compiles but if i try to use these implicits to derive a Gen, then i though that i just would have to modify their return types a bit:

  object Gens {
    import eu.timepit.refined.api.RefType
    import eu.timepit.refined.internal.WitnessAs
    import org.scalacheck.Gen
    import org.scalacheck.Gen.Choose

    implicit def intervalClosedGen[F[_, _]: RefType, T: Numeric: Choose, L, H](
      implicit
      wl: WitnessAs[L, T],
      wh: WitnessAs[H, T]
    ): Gen[F[T, Interval.Closed[L, H]]] = rangeClosedGen(wl.snd, wh.snd)

    private def rangeClosedGen[F[_, _]: RefType, T: Numeric: Choose, P](
      min: T,
      max: T
    ): Gen[F[T, P]] = genRefType(Gen.chooseNum(min, max))

    def genRefType[F[_, _], T, P](gen: Gen[T])(
      implicit rt: RefType[F]
    ): Gen[F[T, P]] = gen.map(rt.unsafeWrap)

    val genSomeIntervalExpl: Gen[SomeInterval] = intervalClosedGen[Refined, Int, W.`0`.T, W.`xFFFE`.T]
    val genSomeInterval: Gen[SomeInterval] = implicitly[Gen[SomeInterval]] // doesnt compile :(
  }

Unfortuneately, this modification breaks the resolution to some extend. Is there an easier way to do this or is there a way to fix this?

Isaias Bartelborth
@isaias-b
Here is also a working snippet in scastie: https://scastie.scala-lang.org/isaias-b/7skM6v1bQySoTk7eySMlzA/8
Jente Hidskes
@Hjdskes
Hi! Simple question here. The README states that refined contains inference rules for converting between different refined types; where can I find which rules are supported? I have a NonEmptyString and a String Refined Size[Interval.Closed[W.1.T, W.70.T]]. Somewhere in my code I assign a variable with the latter type to a field with the former type. Now a string with 1 <= length <= 70 is always non-empty, so I expected refined to infer this, but it doesn't seem to do that. Am I missing something or is this not supported?
Frank S. Thomas
@fthomas
@Hjdskes This conversion is not supported. I guess it would require an implicit instance with the type Not[Empty] ==> Greater[0] but this isn't defined in the library. The inference rules which are currenlty supported can be found in the Inference traits like here and here.
Frank S. Thomas
@fthomas
@isaias-b You don't need to copy the Arbitrary code and change it to Gen. If you just want the underlying Gen of an Arbitrary instance, you can do this: val gen2SomeInterval: Gen[SomeInterval] = Arbitrary.arbitrary[SomeInterval]
Isaias Bartelborth
@isaias-b
OMG i was looking for such thing at the wrong place , pretty obvious though... thanks a lot! :smiley: :+1:
Jente Hidskes
@Hjdskes
Thanks @fthomas, I'll look into adding such an instance. If it works, would you be interested in a PR to add this to the library?
Gabriel Volpe
@gvolpe
Hi there! Is there any way I can define a generic instance of Validate[Long, Size[N]] where N is the arbitrary size?
  implicit val validateSize16: Validate[Long, Size[16]] =
    Validate.fromPredicate[Long, Size[16]](
      _.toString.size == 16,
      _ => "Must have 16 digits",
      Size[16](16)
    )
Right now I'm doing it case by case but there's too much duplication I hope I can avoid
Frank S. Thomas
@fthomas
@gvolpe Something like this should work:
implicit def validateSizeN[N <: Int](implicit w: Witness.Aux[N]): Validate[Long, Size[N]] =
    Validate.fromPredicate[Long, Size[N]](
      _.toString.size == w.value,
      _ => s"Must have ${w.value} digits",
      Size[N](w.value)
    )
Gabriel Volpe
@gvolpe
Awesome, I needed that little bit of help with Shapeless magic! Thanks @fthomas , will give it a try
Frank S. Thomas
@fthomas
If you're on 2.13, you could use Scala's ValueOf[N] instead of Witness.Aux[N]... btw, I'm suddenly reminded that you're still waiting for another answer from me. Sorry about that. Life is busy is always
Gabriel Volpe
@gvolpe
Awesome, yeah I'm on Scala 2.13! And no worries, completely understand :)
One more question: I have a refinement type
type CardNumber = Long Refined Size[16]
But when I call refineV(n), where n is a number of type Long I get the following error
could not find implicit value for parameter v: eu.timepit.refined.api.Validate[Long,P]
I have the generic instance in scope for Validate[Long, Size[N]. Anything I'm missing?
Frank S. Thomas
@fthomas
refineV needs to know with which predicate you want to refine your type, so refineV[Size[16]](n) should work
Gabriel Volpe
@gvolpe
Aha!
Mmm doesn't seem to like it
could not find implicit value for parameter v: eu.timepit.refined.api.Validate[Long,eu.timepit.refined.collection.Size[16]]
Frank S. Thomas
@fthomas
What happens if you change the return type of the Validate instance from Validate[Long, Size[N]] to Validate.Plain[Long, Size[N]]? Does this help?
Gabriel Volpe
@gvolpe
unfortunately not :/
Frank S. Thomas
@fthomas
Gabriel Volpe
@gvolpe
Thanks for the example! I'll see what it is that I'm doing wrong there (more likely :D )
Yeah, it works!
It was my silly mistake of course :smile:
I had N <: Long instead of Int
Gabriel Volpe
@gvolpe
Thanks a lot @fthomas! By the way, all these stuff is part of the content of the application I'm working on, that you're aware of :)
Frank S. Thomas
@fthomas
Very :cool:! :-)