Skip to content

Instantly share code, notes, and snippets.

@gvolpe
Last active July 22, 2022 16:17
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gvolpe/a4c855c43b8c2318597694dc5f42ddbc to your computer and use it in GitHub Desktop.
Save gvolpe/a4c855c43b8c2318597694dc5f42ddbc to your computer and use it in GitHub Desktop.
Scala 3 custom newtypes
type Timestamp = Timestamp.Type
object Timestamp extends Newtype[Instant]
type Quantity = Quantity.Type
object Quantity extends Newtype[Int]
type Source = String
object Source extends Newtype[String]
type SocketId = SocketId.Type
object SocketId extends IdNewtype
import java.util.UUID
import monocle.Iso
trait IsUUID[A]:
def iso: Iso[UUID, A]
object IsUUID:
def apply[A](using ev: IsUUID[A]): IsUUID[A] = ev
given IsUUID[UUID] with
def iso: Iso[UUID, UUID] =
Iso[UUID, UUID](identity)(identity)
import java.util.UUID
import cats.{ Eq, Order, Show }
import io.circe.{ Decoder, Encoder }
import monocle.Iso
abstract class Newtype[A](using
eqv: Eq[A],
ord: Order[A],
shw: Show[A],
enc: Encoder[A],
dec: Decoder[A]
):
opaque type Type = A
inline def apply(a: A): Type = a
protected inline final def derive[F[_]](using ev: F[A]): F[Type] = ev
extension (t: Type) inline def value: A = t
given Eq[Type] = eqv
given Order[Type] = ord
given Show[Type] = shw
given Encoder[Type] = enc
given Decoder[Type] = dec
given Ordering[Type] = ord.toOrdering
abstract class IdNewtype extends Newtype[UUID]:
given IsUUID[Type] = derive[IsUUID]
abstract class NumNewtype[A](using
eqv: Eq[A],
ord: Order[A],
shw: Show[A],
enc: Encoder[A],
dec: Decoder[A],
num: Numeric[A]
) extends Newtype[A]:
extension (x: Type)
inline def -[T](using inv: T =:= Type)(y: T): Type = apply(num.minus(x.value, inv.apply(y).value))
inline def +[T](using inv: T =:= Type)(y: T): Type = apply(num.plus(x.value, inv.apply(y).value))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment