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.NaN This 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.
-
This is a follow-up to:
inline val
foropaque type
alias for literal type 'must have a literal constant type' #13851inline val
foropaque type
alias for literal type is 'declared as erased, but is in fact used' #13852The workaround suggested there is to use an
inline def
instead 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 type
that 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