[英]Tagged type : type mismatch
我尝试使用scalaz中的Tagged Type来加强类型安全性。
我遇到了一个我不明白的警告和错误。
你能解释我两个吗?
这是控制台的输出:
scala> sealed trait PostId
defined trait PostId
scala> def PostId(l: Long) : Long @@ PostId = Tag[Long, PostId](l)
PostId: (l: Long)scalaz.@@[Long,PostId]
warning: previously defined trait PostId is not a companion to method PostId.
Companions must be defined together; you may wish to use :paste mode for this.
scala> case class Post(id: PostId)
defined class Post
scala> Post(PostId(2l))
<console>:26: error: type mismatch;
found : scalaz.@@[Long,PostId]
(which expands to) Long with AnyRef{type Tag = PostId}
required: PostId
Post(PostId(2l))
在您的示例中, PostId
只是一种标记类型。 实际tagg- 版型(你应该操纵型)是Long @@ PostId
。
错误是你已经定义了Post
来获取PostId
的实例,当你真的想让它采用Long @@ PostId
的实例时,因此类型不匹配。
我建议重命名PostId
来PostIdTag
和定义PostId
作为别名Long @@ PostId
:
sealed trait PostIdTag
type PostId = Long @@ PostIdTag
def PostId(l: Long) : PostId = Tag[Long, PostIdTag](l)
然后你可以保持你的Post
定义。
更新 :事实证明,scalaz标记类型似乎只适用于类型<: AnyRef
,即无法从AnyVal
子类型创建标记类型。
然后解决方案是用java.lang.Long
替换Long
(它透明地工作,因为scala会自动将java.lang.Long
值转换为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))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.