Support literal opaque types #17820
Replies: 0 comments 4 replies
-
What is a type literal? Do you mean a literal type? If it was known to be an alias of such type, the opaque type wouldn't be opaque at all. Can't you just use a normal |
Beta Was this translation helpful? Give feedback.
-
|
Thanks for the reply. Apologies, I do mean a literal type. e.g.
With the caveat that I have little theoretical understanding of such things: I have hard time buying this. I don't see why a type can't be both opaque and known to be a literal. Just, an opaque literal :)
Sure, but ideally it would be inlined :) To restate the example I linked to above: opaque type AppendMode <: String = String
object AppendMode {
val segments: AppendMode = "segments"
val sequence: AppendMode = "sequence"
}This is for the scala-js-dom library, where Here we are using an If that's not motivation enough ... here's another example from one of my own libraries: opaque type LogDouble = Double
object LogDouble:
val Zero: LogDouble = Double.NegativeInfinity
val One: LogDouble = 0.0
val Two: LogDouble = 0.6931471805599453
val MinPositiveValue: LogDouble = Double.MinValue
val MaxValue: LogDouble = Double.MaxValue
val PositiveInfinity: LogDouble = Double.PositiveInfinity
val NaN: LogDouble = Double.NaNThis is part of an implementation of the Log semiring: Here, the opaque type is an extremely valuable tool, because it allows us to redefine the However, it would be ideal if the use of |
Beta Was this translation helpful? Give feedback.
-
The problem is that (I do think the special semantics given to What you want is a You can easily find workarounds though. Here is one: object lib:
opaque type AppendMode <: String = String
class Wrap(am: AppendMode) extends AnyVal:
inline def unapply(s: String): Boolean = am == s
extension (self: AppendMode) inline def test: Wrap = Wrap(self)
object AppendMode {
inline def segments: AppendMode = "segments"
inline def sequence: AppendMode = "sequence"
}
def test(x: String) = x match
case lib.AppendMode.segments.test() => "ok"
case _ => "ko"
test(lib.AppendMode.segments) // "ok"The |
Beta Was this translation helpful? Give feedback.
-
Yes, exactly. Well put, thanks.
That's fair, thank you for explaining. IIUC the other important assumption here is that the set of literal types is fixed, and can't be extended? Finally, I appreciate the example, but if you'll forgive me saying so, that looks ... not nice 😆 from a UX pov anyway. Also I thought |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
This is a follow-up to:
inline valforopaque typealias for literal type 'must have a literal constant type' #13851inline valforopaque typealias for literal type is 'declared as erased, but is in fact used' #13852The workaround suggested there is to use an
inline definstead of aninline val, but it's instability prevents it from being helpful for pattern matching against etc.Would it be possible to have an
opaque typethat is known to be an alias to a type literal?For an example use-case see:
inline val? scala-js/scala-js-dom#618Beta Was this translation helpful? Give feedback.
All reactions