首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用抽象类型定义类型约束

用抽象类型定义类型约束
EN

Stack Overflow用户
提问于 2015-06-19 13:50:28
回答 2查看 343关注 0票数 1

我尝试用抽象类型定义类型约束。但不幸的是,它没有编译。

代码语言:javascript
运行
复制
  sealed trait MatchableValue {
    type A
    def value: A

    def asSingleItemValue : ItemValue
  }

  sealed trait ItemValue {
    type A
    def value: A
  }

  case class StringValue(value: String) extends ItemValue {type A = String}
  case class StringMatchableValue(value: String) extends MatchableValue{
    type A = String
    override def asSingleItemValue =  StringValue(value)
  }

不幸的是,这个不起作用

代码语言:javascript
运行
复制
def asSingleItemValue[B <: ItemValue](implicit ev: A =:= B#A) : B

类型约束的目的是在编译时警告此类错误:

代码语言:javascript
运行
复制
  case class IntValue(value: Int) extends ItemValue {type A = Int}
  case class IntMatchableValue(value: Int) extends MatchableValue{
    type A = Int
    def asSingleItemValue = StringValue("error")
  }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-19 15:22:21

您可以通过类型细化(注意该方法的返回类型)来完成这一任务:

代码语言:javascript
运行
复制
sealed trait MatchableValue { self =>
  type A
  def value: A

  def asSingleItemValue: ItemValue { type A = self.A }
}

sealed trait ItemValue {
  type A
  def value: A
}

case class StringValue(value: String) extends ItemValue { type A = String }
case class IntValue(value: Int) extends ItemValue { type A = Int }

现在,这将编译:

代码语言:javascript
运行
复制
case class StringMatchableValue(value: String) extends MatchableValue {
  type A = String
  def asSingleItemValue = StringValue(value)
}

但这并不是:

代码语言:javascript
运行
复制
case class StringMatchableValue(value: String) extends MatchableValue {
  type A = String
  def asSingleItemValue = IntValue(1)
}

我相信这就是你想要的。

还值得注意的是,在处理类型细化时,以下是常见的模式:

代码语言:javascript
运行
复制
sealed trait MatchableValue { self =>
  type A
  def value: A

  def asSingleItemValue: ItemValue.Aux[A]
}

sealed trait ItemValue {
  type A
  def value: A
}

object ItemValue {
  type Aux[A0] = ItemValue { type A = A0 }
}

这做了完全相同的事情,但是如果您发现自己需要大量地写出类型细化,那么语法是一个不错的选择。

票数 6
EN

Stack Overflow用户

发布于 2015-06-19 14:03:59

我想你是想在你的代码中删除这一行?

代码语言:javascript
运行
复制
def asSingleItemValue = StringValue(value)

override定义中缺少了一些签名,应该如下所示:

代码语言:javascript
运行
复制
override def asSingleItemValue[B <: ItemValue](implicit ev: =:=[String, B#A]): B = ev

最后,产生的ev类型需要是B

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30939868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档