fthomas/refined

[discussion] eliminating macro dependency for `refineMV`

erikerlandson opened this issue · 2 comments

moving this sub-discussion on #758 to its own topic for clarity

It seems like it could be possible for refined to go completely macro-less, if (for example) refineMV[Positive](5) was instead written as refineMV[Positive, 5].

This would involve the compile-time refineMV leaning totally on singleton-ops, and expressions of the (pseudo)form implicit valid: OpAuxBoolean[P[V], true]. In that respect, all the macros get pushed to singleton-ops. fthomas/singleton-ops#134 would probably get singleton-ops close to supporting all of refined, maybe not all the way. It could put refined in a better position for scala 3, and localize all the macro porting to singleton-ops.

In pre-2.13 scala this would not be as nice: refineMV[Positive, W.5.T], but the future is first-class literal types.

A possible alternative would be to use scala trickery to bind the literal type from the parameter:

scala> def foo[T <: Singleton](ce: T)(implicit tt: WeakTypeTag[T]): String = tt.tpe.toString
foo: [T <: Singleton](ce: T)(implicit tt: WeakTypeTag[T])String

scala> foo(5)
res34: String = Int(5)

scala> foo(x)
res35: String = x.type

scala> foo("abc")
res36: String = String("abc")

I'm interested in the possibility of somehow unifying run-time (refineV) with compile-time refineMV, via the Validate implicit system. I am not sure if it's feasible. Maybe it could be done by adding some kind of type Pred[L] to Validate, where one could compile-time test OpAuxBoolean[Pred[L], true] in the case of refineMV, and so compile-time and run-time tests are built-up in parallel via Validate.

Sad, def foo[T <: Singleton](ce: T) doesn't work on scala 2.12