Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala中的链接类型_Scala_Dependent Type - Fatal编程技术网

Scala中的链接类型

Scala中的链接类型,scala,dependent-type,Scala,Dependent Type,我有一类对象,它们要么具有一种类型的ID,要么具有另一种类型的ID: sealed trait ItemId case class NumericId(id: Int) extends ItemId case class StringId(id: String) extends ItemId sealed trait Item { def id: ItemId } case class ItemWithNumericId(id: NumericId) extends Item case

我有一类对象,它们要么具有一种类型的ID,要么具有另一种类型的ID:

sealed trait ItemId
case class NumericId(id: Int) extends ItemId
case class StringId(id: String) extends ItemId

sealed trait Item {
  def id: ItemId
}

case class ItemWithNumericId(id: NumericId) extends Item
case class ItemWithStringId(id: StringId) extends Item
我想为某种检索项目的服务创建一个接口:

trait ItemService[IdType <: ItemId, ItemType <: Item] {
  def get(id: IdType): ItemType
}

我意识到我可以将泛型类型添加到
类:

sealed trait ItemId
case class NumericId(id: Int) extends ItemId
case class StringId(id: String) extends ItemId

sealed trait Item[Id <: ItemId] {
  def id: Id
}

case class ItemWithNumericId(id: NumericId) extends Item[NumericId]
case class ItemWithStringId(id: StringId) extends Item[StringId]

trait ItemService[IdType <: ItemId, ItemType <: Item[IdType]] {
  def get(id: IdType): ItemType
}
ItemId
case类NumericId(id:Int)扩展了ItemId
case类StringId(id:String)扩展了ItemId

密封特征项[Id可能是这样的吗

 trait Item {
    type IdType
    def id: IdType
 }

 trait ItemService[I <: Item] {
   def get(id: I#IdType): Item
 }
trait项{
类型IdType
定义id:IdType
}

trait-ItemService[I路径依赖类型是另一个答案所涵盖的一个选项,但出于灵活性的目的,在本例中,我个人将使用隐式/上下文边界

trait Proof[IdType <: ItemId, ItemType <: Item[IdType]]

trait ItemService[IdType <: ItemId, ItemType <: Item[IdType]] {
  def get(id: IdType)(implicit ev: Proof[IdType, ItemType])
}

在这一点上,您并不真正关心您的服务是什么样子的,尽管f有界多态性稍后可能允许您进行超细粒度控制,因为您可以专门针对特定的实现进行隐式操作,并创建模糊的证明,在这些证明中,您希望为不打算混合在一起的内容提供编译时错误。

我的做法是:

sealed trait ItemId
case class NumericId(id: Int) extends ItemId
case class StringId(id: String) extends ItemId

trait Item[A <: ItemId] {
  def id: A
}

trait ItemService[A <: ItemId, B <: Item[A]] {
  def get(id: A): B
}

这真的很好。
ItemService
的实现有我想要的约束,它们可以用最少的样板代码声明。谢谢!
object Proof {
  implicit numericProof: Proof[NumericId, ItemWithNumericId] = new Proof[NumericId, ItemWithNumericId] {}
  ...
}
sealed trait ItemId
case class NumericId(id: Int) extends ItemId
case class StringId(id: String) extends ItemId

trait Item[A <: ItemId] {
  def id: A
}

trait ItemService[A <: ItemId, B <: Item[A]] {
  def get(id: A): B
}
trait ItemService[A <: ItemId] {
  def get(id: A): Item[A]
}