In your example, PostId
is just a tag type.
The actual tagg-ed type (the type that you should manipulate) is Long @@ PostId
.
The error is that you have defined Post
to take an instance of PostId
when you really meant to have it take an instance of Long @@ PostId
, hence the type mismatch.
I suggest renaming PostId
to PostIdTag
and defining PostId
as an alias to Long @@ PostId
:
sealed trait PostIdTag
type PostId = Long @@ PostIdTag
def PostId(l: Long) : PostId = Tag[Long, PostIdTag](l)
Then you can keep your Post
definition as is.
UPDATE: As it turns out, scalaz tagged types seem to only work with types <: AnyRef
, ie one cannot create a tagged type from an AnyVal
sub-type.
The solution then is to replace Long
with java.lang.Long
(which works transparently because scala will automatically convert java.lang.Long
values to Long
):
sealed trait PostIdTag
type PostId = java.lang.Long @@ PostIdTag
def PostId(l: java.lang.Long) : PostId = Tag[java.lang.Long, PostIdTag](l)
case class Post(id: PostId)
Post(PostId(2l))