Last active
July 22, 2022 16:17
-
-
Save gvolpe/a4c855c43b8c2318597694dc5f42ddbc to your computer and use it in GitHub Desktop.
Scala 3 custom newtypes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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