In dotty there is opaque
type where you can just define something like
opaque type NonEmptyString = String
object NonEmptyString:
def apply(s: String): Either[Error, NonEmptyString] = ???
This ensures that the only way of creating a NonEmptyString
is via the apply method of object NonEmptyString
. Can something similar be done in Scala 2.13?
1 Like
Not as nice and concise, but, well…
2 Likes
You can encode the same thing with some extra boilerplate.
scala> trait NonEmptyString {
| type Type
| def apply(s: String): Option[Type]
| }
trait NonEmptyString
scala> val NonEmptyString: NonEmptyString = new NonEmptyString {
| type Type = String
| def apply(s: String): Option[Type] = Option.when(s.nonEmpty)(s)
| }
val NonEmptyString: NonEmptyString = $anon$1@5f7599fd
scala> val nes = NonEmptyString("foo")
val nes: Option[NonEmptyString.Type] = Some(foo)
1 Like
But the type of nes
is not NonEmptyString
instead it is Option[NonEmptyString.Type]
.
Yes, in this case NonEmptyString.Type
is the equivalent of the opaque type NonEmptyString
in dotty. Alternatively you could do
scala> trait Opaque {
| type NonEmptyString
| def NonEmptyString(s: String): Option[NonEmptyString]
| }
trait Opaque
scala> val Opaque: Opaque = new Opaque {
| type NonEmptyString = String
| def NonEmptyString(s: String): Option[NonEmptyString] = Option.when(s.nonEmpty)(s)
| }
val Opaque: Opaque = $anon$1@728f8064
scala> import Opaque._
import Opaque._
scala> val nes: Option[NonEmptyString] = NonEmptyString("foo")
val nes: Option[Opaque.NonEmptyString] = Some(foo)
Top level objects is not possible in Scala 2.13. So the code,
val NonEmptyString: NonEmptyString = new NonEmptyString {
type Type = String
def apply(s: String): Option[Type] = Option.when(s.nonEmpty)(s)
}
Will have to go inside an object
and the type will no longer be NonEmptyString.Type
. It will instead be <object-name>.NonEmptyString.Type
True. And the same would be true if Scala 2.13 had the opaque types feature. The opaque type and its companion object couldn’t be top level either.
1 Like
Package object to the rescue, perhaps?
1 Like