These are chat archives for fthomas/refined

25th
Dec 2016
Oron Port
@soronpo
Dec 25 2016 13:49
@fthomas Is there a way to include implicit conversion to a refined type in a library without requiring the user to call import eu.timepit.refined.auto._?
For example https://github.com/fthomas/refined/blob/master/modules/docs/nonnegint.md
If def element[T](seq: Seq[T], j: NonNegInt) = seq(j) would have been a part of a library, then the user of that library would be required to import eu.timepit.refined.auto._ along with the library
Frank S. Thomas
@fthomas
Dec 25 2016 13:55
Yes, that is right. Maybe if the implicit conversion would be in the companion of Refined, the import wouldn't be necessary.
If the library defines its own predicate, the auto trait could be mixed into the companion of these predicates. That should also make that import unnecessary
Oron Port
@soronpo
Dec 25 2016 13:58
OK, I'll try to define my own predicate. Thanks!
Frank S. Thomas
@fthomas
Dec 25 2016 14:01
@soronpo It would be interesting to know if this works or not.
Oron Port
@soronpo
Dec 25 2016 14:02
I'll check and update you.
Frank S. Thomas
@fthomas
Dec 25 2016 14:02
:+1:
Oron Port
@soronpo
Dec 25 2016 14:26

@fthomas Even if I do the following in console:

import eu.timepit.refined.api.Validate
case class ZeroOrOne()
implicit val quadrant1Validate: Validate.Plain[Int, ZeroOrOne] =
  Validate.fromPredicate(p => p == 0 || p == 1, p => s"($p is in not binary)", ZeroOrOne())

refineMV[ZeroOrOne](0) //As expected
refineMV[ZeroOrOne](1) //As expected
refineMV[ZeroOrOne](2) //As expected (error: Predicate failed: (2 is in not binary))

def libFunc(x : ZeroOrOne) = {}
libFunc(1) // error: type mismatch;

How do I create my own implicit as refineMV?

Oron Port
@soronpo
Dec 25 2016 16:48
@fthomas On a different issue, I thought of a nice design pattern to combine safe and unsafe definitions (maybe it is already known, but not to me):
  trait Unsafe
  object Unsafe extends Unsafe

  trait Binary 
  object Binary {
    def apply(constVal : 0) : Int = 0
    def apply(constVal : 1)(implicit dummy : DummyImplicit) : Int = 1
    def apply(constVal : Int)(implicit unsafe: Unsafe) : Int = constVal match {
      case 0 => 0
      case 1 => 1
    }
  }

  object SafeTest {
    val zero = Binary(0)
    val one = Binary(1)
    val failing = Binary(2) //fails at compile-time
  }

  object UnsafeTest {
    implicit val unsafe = Unsafe //must be used to allow `i`
    for (i <- 0 to 2)
      Binary(i) //fails at run-time
  }
Frank S. Thomas
@fthomas
Dec 25 2016 21:02
@soronpo your libFunc needs to take an Int Refined ZeroOrOne instead of ZeroOrOne. The latter is only the predicate and not a proper type that is constrained by a predicate
Oron Port
@soronpo
Dec 25 2016 22:04
def libFunc(x : Int Refined ZeroOrOne) = {}

Still gets

scala> libFunc(1)
<console>:24: error: type mismatch;
 found   : Int(1)
 required: eu.timepit.refined.api.Refined[Int,ZeroOrOne]
       libFunc(1)

Only import eu.timepit.refined.auto._ resolves this, meaning the user of the library has to do this.
(If only Scala had some sort of export mechanism, but that's a feature that will make a mess of things.)

Frank S. Thomas
@fthomas
Dec 25 2016 22:14
What if you add the following companion object ZeroOrOne extends eu.timepit.refined.auto? If you're trying this in the REPL you have to define ZeroOrOne and its companion with :paste so that both are defined in the same package.
Oron Port
@soronpo
Dec 25 2016 22:21
I cannot extend auto
Frank S. Thomas
@fthomas
Dec 25 2016 22:22
You're right, my bad. auto was both a trait and object in a prior version.
Oron Port
@soronpo
Dec 25 2016 22:23
I'm trying to copy paste it into my code as a trait now to see if this will help
Frank S. Thomas
@fthomas
Dec 25 2016 22:27
The idea here is to bring the implicit conversions in the implicit scope of your refined type.
Oron Port
@soronpo
Dec 25 2016 22:30
Nice! works!
Frank S. Thomas
@fthomas
Dec 25 2016 22:31
Cool!
Oron Port
@soronpo
Dec 25 2016 22:31
Ok, I'll submit a issue requesting (re)separating auto to a trait and object
?
And detail the use case of course
maybe the trait should have a better name though
Frank S. Thomas
@fthomas
Dec 25 2016 22:33
:+1:
Frank S. Thomas
@fthomas
Dec 25 2016 22:57
Btw, I think if we mix auto into the Refined companion, we would make the auto import unnecessary for all Refined types . Not sure if this is a good idea, though.