sir-wabbit/newtypes

Scala

114

2 commits

updated Mar 28, 2022

See the code

README

Newts

Better newtypes for Scala based on the following two articles:

Quick Start

addCompilerPlugin("org.scalameta" % "paradise" % "3.0.0-M10" cross CrossVersion.full)
resolvers += Resolver.bintrayRepo("alexknvl", "maven")
libraryDependencies += "com.alexknvl"  %%  "newtypes" % "0.3.0"

Use this fork of scalameta/paradise until https://github.com/scalameta/paradise/pull/207 is merged in if you need companion object support and can't use paradise-3.0.0-M10 (it supports only 2.12.3+). Clone it and publishM2 in sbt, then change the paradise plugin to:

addCompilerPlugin("org.scalameta" % "paradise" % "3.0.0-alex" cross CrossVersion.full)

Why newts?

FeaturesAnyVal@newtypes.opaque@newtypes.translucent
isInstanceOfYesNoNo
Generics box AnyRef subtypesYesNoNo
Generics box primitivesYesYesYes
Primitives boxNoYesNo
Up-cast worksNoNoYes
Down-cast worksNoNoNo
Any methodsYesYesYes
OverridesYesNoNo
Virtual dispatchYesNoNo
Typeclass-based dispatchYesYesYes
Wrap List elementsO(N)O(1) (using subst)O(1) (using subst)
Unwrap List elementsO(N)O(1) (using subst and Is)O(1) (automatic widening)
Supports HK parametersYesYesYes
Supports existential parametersYesYesYes

What does it do?

@opaque type ArrayWrapper[A] = Array[A]

@translucent type Flags = Int

becomes

type ArrayWrapper[A] = ArrayWrapper.Type[A]
object ArrayWrapper {
  type Base$$1
  trait Tag$$1 extends Any
  type Type[A] <: Base$$1 with Tag$$1
  
  object Impl {
    def apply[A](value: Array[A]): Type[A] = value.asInstanceOf[Type[A]]
    def unwrap[A](value: Type[A]): Array[A] = value.asInstanceOf[Array[A]]
    def subst[F[_], A](value: F[Array[A]]): F[Type[A]] = value.asInstanceOf[F[Type[A]]]
  }
}

type Flags = Flags.Type
object Flags {
  trait Tag$$1 extends Any
  type Type <: Int with Tag$$1
  object Impl {
    def apply(value: Int): Type = value.asInstanceOf[Type]
    def unwrap(value: Type): Int = value.asInstanceOf[Int]
    def subst[F[_]](value: F[Int]): F[Type] = value.asInstanceOf[F[Type]]
  }
}

License

Code is provided under the MIT license available at https://opensource.org/licenses/MIT, as well as in the LICENSE file.

newtype
scala

Contributors

coltfred

2 commits

sir-wabbit/newtypes

Scala

114

2 commits

updated Mar 28, 2022

See the code

README

Newts

Better newtypes for Scala based on the following two articles:

Quick Start

addCompilerPlugin("org.scalameta" % "paradise" % "3.0.0-M10" cross CrossVersion.full)
resolvers += Resolver.bintrayRepo("alexknvl", "maven")
libraryDependencies += "com.alexknvl"  %%  "newtypes" % "0.3.0"

Use this fork of scalameta/paradise until https://github.com/scalameta/paradise/pull/207 is merged in if you need companion object support and can't use paradise-3.0.0-M10 (it supports only 2.12.3+). Clone it and publishM2 in sbt, then change the paradise plugin to:

addCompilerPlugin("org.scalameta" % "paradise" % "3.0.0-alex" cross CrossVersion.full)

Why newts?

FeaturesAnyVal@newtypes.opaque@newtypes.translucent
isInstanceOfYesNoNo
Generics box AnyRef subtypesYesNoNo
Generics box primitivesYesYesYes
Primitives boxNoYesNo
Up-cast worksNoNoYes
Down-cast worksNoNoNo
Any methodsYesYesYes
OverridesYesNoNo
Virtual dispatchYesNoNo
Typeclass-based dispatchYesYesYes
Wrap List elementsO(N)O(1) (using subst)O(1) (using subst)
Unwrap List elementsO(N)O(1) (using subst and Is)O(1) (automatic widening)
Supports HK parametersYesYesYes
Supports existential parametersYesYesYes

What does it do?

@opaque type ArrayWrapper[A] = Array[A]

@translucent type Flags = Int

becomes

type ArrayWrapper[A] = ArrayWrapper.Type[A]
object ArrayWrapper {
  type Base$$1
  trait Tag$$1 extends Any
  type Type[A] <: Base$$1 with Tag$$1
  
  object Impl {
    def apply[A](value: Array[A]): Type[A] = value.asInstanceOf[Type[A]]
    def unwrap[A](value: Type[A]): Array[A] = value.asInstanceOf[Array[A]]
    def subst[F[_], A](value: F[Array[A]]): F[Type[A]] = value.asInstanceOf[F[Type[A]]]
  }
}

type Flags = Flags.Type
object Flags {
  trait Tag$$1 extends Any
  type Type <: Int with Tag$$1
  object Impl {
    def apply(value: Int): Type = value.asInstanceOf[Type]
    def unwrap(value: Type): Int = value.asInstanceOf[Int]
    def subst[F[_]](value: F[Int]): F[Type] = value.asInstanceOf[F[Type]]
  }
}

License

Code is provided under the MIT license available at https://opensource.org/licenses/MIT, as well as in the LICENSE file.

newtype
scala

Contributors

coltfred

2 commits

Languages

Scala

100.0%