5

说我有这个:

  trait Animal {
    type Species
  }

我可以很容易地编写一个只需要两个相同物种的动物的函数

def breed(a: Animal, b: Animal)(implicit evidence: a.Species =:= b.Species) = ???

但我想创建一个具有相同约束的类:

class Bed(a: Animal, b: Animal)(implicit evidence: a.Species =:= b.Species)

但它不会编译。我尝试了一些尝试使用具有稳定标识符和约束的特征的组合,但无论我做什么 - 我似乎总是遇到问题

  trait Bed {
    type T
    def a: Animal { type Species = T }
    def b: Animal { type Species = T }
  }

  object Bed {

    def apply(a1: Animal, b1: Animal)(implicit ev: a1.Species =:= b1.Species) = new Bed {
      type T = b1.Species
      def a = a1  // this line won't compile,  as the compiler can't see the two species are equal ?
      def b = b1 
    }

  }

谢谢。

4

1 回答 1

4

您可以通过 Bed.apply 上的类型参数而不是通过类型相等约束来表达约束,

object Bed {
  def apply[T1](
    a1: Animal { type Species = T1 },
    b1: Animal { type Species = T1 }) = new Bed {
    type T = T1
    def a = a1
    def b = b1
  }
}

这可以在类型别名的帮助下变得更简洁,

type AnimalAux[S] = Animal { type Species = S }

object Bed {
  def apply[T1](a1: AnimalAux[T1], b1: AnimalAux[T1]) =
    new Bed {
      type T = T1
      def a = a1
      def b = b1
    }
}

示例 REPL 会话,

scala> trait Dog
defined trait Dog

scala> val tigger = new Animal { type Species = Dog }
tigger: Animal{type Species = Dog} = $anon$1@64bd8f9c

scala> val zebedee = new Animal { type Species = Dog }
zebedee: Animal{type Species = Dog} = $anon$1@61f2bf35

scala> Bed(tigger, zebedee)
res0: Bed{type T = Dog} = Bed$$anon$1@2b0ce330

scala> val b = Bed(tigger, zebedee)
b: Bed{type T = Dog} = Bed$$anon$1@681c81de
于 2013-04-07T23:31:12.047 回答