Yea sometimes detailed explanation can sound difficult than:

https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/typeoperators.scala, or

https://github.com/rudogma/scala-supertagged

or

https://gist.github.com/nodemvc/6735a8bf0699256d199db7ac9cad0dbb

or just

trait NewType[A]{
type MyType <: A
def wrap(a: A): MyType
def unwrap(myType: MyType): A
def wrapAll[F[_]](fa: F[A]): F[MyType] = fa
def unwrapAll[F[_]](fm: F[MyType]): F[A] = fm
}
def newType[A] = new NewType[A]{
type MyType = A
def wrap(a:A): MyType = a
def unwrap(myType: MyType): A = a
def wrapAll[F[_]](fa: F[A]): F[MyType] = fa
def unwrapAll[F[_]](fm: F[MyType]): F[A] = fm
}

And I really hope, you do get the fact you are not writing this interface in your application code everytime. The pain is taken to a library which will be released.

But the pain of auto-derivation + too many implicit derivations for primitive typeclasses while we define one for new types + associated shapeless-code + unwrapping tags for functions that requires in application types is taken off.

If your question was why tagged types, well this blog doesn’t even start with what is a tagged type :)

A software engineer and a functional programming enthusiast at Simple-machines, Sydney, and a hardcore hiking fan. https://twitter.com/afsalt2

A software engineer and a functional programming enthusiast at Simple-machines, Sydney, and a hardcore hiking fan. https://twitter.com/afsalt2