--
Yea sometimes detailed explanation can sound difficult than:
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 :)