Scala MyType类型不匹配

Scala MyType类型不匹配,scala,types,self-type,Scala,Types,Self Type,我从他那里借用了MyType的技巧。但最近我遇到了自我类型的问题。一个例子说明了我的意思: trait Excitable[SELF] { self: SELF => def withMoreAnger: SELF } trait Animal[SELF0] { self: SELF0 => type SELF = SELF0 // to reveal SELF0 for method spitAt used as a dependent method type typ

我从他那里借用了MyType的技巧。但最近我遇到了自我类型的问题。一个例子说明了我的意思:

trait Excitable[SELF] { self: SELF =>
  def withMoreAnger: SELF
}
trait Animal[SELF0] { self: SELF0 =>
  type SELF = SELF0 // to reveal SELF0 for method spitAt used as a dependent method type 
  type SpittableAnimal[S] <: Animal[S]
  def spitAt[A <: SpittableAnimal[_]](a: A): a.SELF
}
trait ExcitableAnimal[SELF] extends Animal[SELF] with Excitable[SELF] { self: SELF =>
  type SpittableAnimal[S] = ExcitableAnimal[S]
  def spitAt[A <: SpittableAnimal[_]](a: A): a.SELF = a.withMoreAnger
}
trait Quadruped[SELF] extends ExcitableAnimal[SELF] { self: SELF => }
case class Dog(anger: Int) extends Quadruped[Dog] {
  def withMoreAnger: Dog = copy(anger = anger + 1)
}
case class Cat(anger: Int) extends Quadruped[Cat] {
  def withMoreAnger: Cat = copy(anger = anger + 1)
}
val dog = Dog(anger = 0)
val cat = Cat(anger = 0)
val angryCat: Cat = dog spitAt cat // fine

val anotherDog = Dog(0)
val animals = Seq(dog, cat)
val angryAnimals: Seq[Quadruped[_]] = for (a <- animals) yield anotherDog spitAt a // fine
val veryAngryAnimals: Seq[Quadruped[_]] = for (a <- angryAnimals) yield anotherDog spitAt a // type mismatch !!!

但是,推断的类型参数不符合方法spitAt的类型参数界限,这一点我很清楚,因为
动物
中元素的
SELF
类型参数至少受
\u>:Cat with Dog的限制。你喜欢zee痛苦吗?是吗!:)

我不敢相信这个问题没有爱

$ smala spit.Test
List(mild puppy, sweet kitteh)
List(angry puppy, gnarly kitteh)
List(angry hound, gnarly pussy)
谁能抵抗这只粗糙的小猫

快给我投票,否则小猫会生气的!非常生气

在关于MyType的问题中,我们发现有人说只使用类型类。就这么做吧

很容易批准谁可能吐口水和被吐口水,也很容易阅读代码,也许

我本想变得聪明,例如,一只非常愤怒的猫变成了一只幽灵猫(愤怒>9条生命),但我必须去幼儿园当司机

package spit

import language.{ higherKinds, implicitConversions }

trait Excitable[SELF] { self: SELF =>
  def withMoreAnger: SELF
}
trait Animal[SELF] { self: SELF =>
  type SpatAt = SELF
  type SpittableAnimal[S] <: Animal[S]
}
trait ExcitableAnimal[SELF] extends Animal[SELF] with Excitable[SELF] { self: SELF =>
}
object ExcitableAnimal{
  implicit def toSpitter[S](a: ExcitableAnimal[S]) = new Spitter(a)
  implicit def toSpittee[S](a: ExcitableAnimal[S]) = new Spittee(a)
}
trait Quadruped[SELF] extends ExcitableAnimal[SELF] { self: SELF =>
}
class Dog(anger: Int) extends Quadruped[Dog] {
  def withMoreAnger: Dog = new Dog(anger + 2)
  override def toString = s"${if (anger > 0) "angry" else "mild"} ${if (anger > 2) "hound" else "puppy"}"
}
class Cat(anger: Int) extends Quadruped[Cat] {
  def withMoreAnger: Cat = new Cat(anger + 1)
  override def toString = s"${if (anger > 0) "gnarly" else "sweet"} ${if (anger > 1) "pussy" else "kitteh"}"
}

class Spitter[S](val spitter: Animal[S]) extends AnyVal {
  def spitAt[T](spittee: ExcitableAnimal[T]) = spittee.spatUpon
}
class Spittee[S](val spittee: ExcitableAnimal[S]) extends AnyVal {
  def spatUpon = spittee.withMoreAnger
}
object Test {
  def Dog(anger: Int) = new Dog(anger)
  def Cat(anger: Int) = new Cat(anger)
  def main(args: Array[String]) {
    val dog = Dog(anger = 0)
    val cat = Cat(anger = 0)
    val angryCat: Cat = dog spitAt cat // fine

    val anotherDog = Dog(0)
    val animals = Seq(dog, cat)
    println(animals)
    val angryAnimals = for (a <- animals) yield anotherDog spitAt a
    println(angryAnimals)
    val poAnimals = for (a <- angryAnimals) yield anotherDog spitAt a
    println(poAnimals)
  }
}
包吐
导入语言。{higherKinds,implicitConversions}
特质易兴奋[自我]{SELF:SELF=>
更愤怒的定义:自我
}
特质动物[自我]{SELF:SELF=>
斯帕塔特类型=自我
可食动物[S]
}
对象兴奋动物{
隐式def toSpitter[S](a:ExceptibleAnimal[S])=新吐痰器(a)
隐式定义toSpittee[S](a:ExceptibleAnimal[S])=新Spittee(a)
}
四足动物[SELF]的特征扩展兴奋性动物[SELF]{SELF:SELF=>
}
类狗(愤怒:智力)扩展四足动物[狗]{
def withMoreAnger:Dog=新狗(anger+2)
override def toString=s“${if(anger>0)“anger”else“温和”}${if(anger>2)“hound”else“puppy”}”
}
猫类(anger:Int)扩展四足动物[猫]{
def withMoreAnger:Cat=新的Cat(anger+1)
override def toString=s“${if(anger>0)“gnarly”else“sweet”}${if(anger>1)“pussy”else“kitteh”}”
}
类Spitter[S](val Spitter:Animal[S])扩展了AnyVal{
def spitAt[T](spittee:excitibleanimal[T])=spittee.spaton
}
类Spittee[S](val Spittee:ExceptiableAnimal[S])扩展了AnyVal{
def SPATON=spittee.withmorearge
}
对象测试{
def狗(愤怒:智力)=新狗(愤怒)
def Cat(anger:Int)=新的Cat(anger)
def main(参数:数组[字符串]){
瓦尔狗=狗(愤怒=0)
瓦尔猫=猫(愤怒=0)
val angryCat:Cat=狗吐猫//很好
val anotherDog=狗(0)
val动物=顺序(狗、猫)
println(动物)

val AngryAnimages=for(a这里是另一个镜头。我猜这将是“吐镜头”

它只显示类型参数的差异,以及spitAt的修改签名

在Worm中,它还展示了另一个永恒问题的示例,让您创建一个包含抽象类型成员的具体类有什么好处

package spit

import language.higherKinds

trait Excitable[+SELF] { self: SELF =>
  def withMoreAnger: SELF
}
trait Animal[+SELF] { self: SELF =>
  type SpatAt = SELF // to reveal SELF for method spitAt used as a dependent method type
  type SpittableAnimal[S] <: Animal[S]
  def spitAt[A](a: SpittableAnimal[A]): a.SpatAt
}
trait ExcitableAnimal[+SELF] extends Animal[SELF] with Excitable[SELF] { self: SELF =>
  type SpittableAnimal[S] = ExcitableAnimal[S]
  def spitAt[A](a: SpittableAnimal[A]): a.SpatAt = a.withMoreAnger
}
trait Quadruped[+SELF] extends ExcitableAnimal[SELF] { self: SELF =>
}
case class Dog(anger: Int) extends Quadruped[Dog] {
  def withMoreAnger: Dog = copy(anger = anger + 1)
}
case class Cat(anger: Int) extends Quadruped[Cat] {
  def withMoreAnger: Cat = copy(anger = anger + 1)
}
trait Vermiform[SELF] extends Animal[SELF] { self: SELF =>
  // worm saliva is actually quite pleasant
  def spitAt[A](a: SpittableAnimal[A]): a.SpatAt = a.asInstanceOf[A]
}
case class Worm() extends Vermiform[Worm]

object Test {
  def main(args: Array[String]) {
    val dog = Dog(anger = 0)
    val cat = Cat(anger = 0)
    val angryCat: Cat = dog spitAt cat // fine

    val anotherDog = Dog(0)
    val animals = Seq(dog, cat)
    val angryAnimals = for (a <- animals) yield anotherDog spitAt a
    val podAnimals = for (a <- angryAnimals) yield anotherDog spitAt a
    println(animals)
    println(angryAnimals)
    println(podAnimals)

    val worm = Worm()
    //println(worm spitAt dog) // Worms don't spit
  }
}
包吐
导入语言
特质易兴奋[+自我]{SELF:SELF=>
更愤怒的定义:自我
}
特质动物[+SELF]{SELF:SELF=>
键入spatt=SELF//以显示用作依赖方法类型的方法spitAt的SELF
可食动物[S]
可吐性动物[S]=兴奋性动物[S]
例如:可吐痰的动物;可吐痰的动物
}
四足动物[+SELF]扩展兴奋性动物[SELF]{SELF:SELF=>
}
案例类狗(愤怒:智力)扩展四足动物[狗]{
def withMoreAnger:Dog=复制(anger=anger+1)
}
案例类猫(anger:Int)扩展四足动物[猫]{
def withMoreAnger:Cat=copy(anger=anger+1)
}
特征虫形[SELF]扩展动物[SELF]{SELF:SELF=>
//虫子的唾液其实很令人愉快
例如:可吐的动物;可吐的动物
}
案例类Worm()扩展了蠕虫[Worm]
对象测试{
def main(参数:数组[字符串]){
瓦尔狗=狗(愤怒=0)
瓦尔猫=猫(愤怒=0)
val angryCat:Cat=狗吐猫//很好
val anotherDog=狗(0)
val动物=顺序(狗、猫)

val AngryAnimages=for(a与此同时,我继续阅读并记住了这一条:
如前所述,TypeClass值得一试。因此:

trait Excitable[T] { // TYPECLASS
  def withMoreAnger(t: T): T
}
trait Animal {
  type SpittableAnimal <: Animal
  def spitAt[A <: SpittableAnimal: Excitable](a: A): A
}
trait ExcitableAnimal extends Animal {
  type SpittableAnimal = ExcitableAnimal
  def spitAt[A <: SpittableAnimal: Excitable](a: A): A = implicitly[Excitable[A]] withMoreAnger a
}

object Dog {
  implicit object ExcitableDog extends Excitable[Dog] {
    def withMoreAnger(dog: Dog): Dog = dog copy (anger = dog.anger + 1)
  }
}
case class Dog(anger: Int) extends Quadruped

object Cat {
  implicit object ExcitableCat extends Excitable[Cat] {
    def withMoreAnger(cat: Cat): Cat = cat copy (anger = cat.anger + 1)
  }
}
case class Cat(anger: Int) extends Quadruped

sealed trait Quadruped extends ExcitableAnimal // sealed: to couple pattern match at implicit object ExcitableQuadruped and all subclasses of Quadruped
object Quadruped {
  implicit object ExcitableQuadruped extends Excitable[Quadruped] {
    def withMoreAnger(quadruped: Quadruped): Quadruped = {
      quadruped match {
        case dog: Dog => implicitly[Excitable[Dog]].withMoreAnger(dog)
        case cat: Cat => implicitly[Excitable[Cat]].withMoreAnger(cat)
      }
    }
  }
}

val dog = Dog(anger = 0)
val cat = Cat(anger = 0)
val angryCat: Cat = dog spitAt cat // fine
val anotherDog = Dog(0)
val animals: Seq[Quadruped] = Seq(dog, cat)
val angryAnimals: Seq[Quadruped] = for (a <- animals) yield anotherDog spitAt a // fine
val podAnimals: Seq[Quadruped] = for (a <- angryAnimals) yield anotherDog spitAt a // fine, still a Seq[Quadruped]
trait兴奋性[T]{//TYPECLASS
def with moreanger(t:t):t
}
特征动物{

键入SpittableAnimal抱歉,但我无法使用scala 2.9.3编译您的代码:
angryAnimals
-行:
方法spitAt没有类型参数:(spittee:Excigatibleanimal[t])不存在,因此它可以应用于参数(四足动物)[\u>:Cat with Dog:Cat with Dog感谢您的方法!一个严重的问题仍然存在:如果您为(A)插入
val hoppingmadampanies=
trait Vermiform[SELF] extends Animal[SELF] { self: SELF =>
  // worm saliva is actually quite pleasant
  def spitAt[A <: SpittableAnimal[A]](a: A): a.SpatAt = a
} // not excitable
case class Worm() extends Vermiform[Worm]
package spit

import language.higherKinds

trait Excitable[+SELF] { self: SELF =>
  def withMoreAnger: SELF
}
trait Animal[+SELF] { self: SELF =>
  type SpatAt = SELF // to reveal SELF for method spitAt used as a dependent method type
  type SpittableAnimal[S] <: Animal[S]
  def spitAt[A](a: SpittableAnimal[A]): a.SpatAt
}
trait ExcitableAnimal[+SELF] extends Animal[SELF] with Excitable[SELF] { self: SELF =>
  type SpittableAnimal[S] = ExcitableAnimal[S]
  def spitAt[A](a: SpittableAnimal[A]): a.SpatAt = a.withMoreAnger
}
trait Quadruped[+SELF] extends ExcitableAnimal[SELF] { self: SELF =>
}
case class Dog(anger: Int) extends Quadruped[Dog] {
  def withMoreAnger: Dog = copy(anger = anger + 1)
}
case class Cat(anger: Int) extends Quadruped[Cat] {
  def withMoreAnger: Cat = copy(anger = anger + 1)
}
trait Vermiform[SELF] extends Animal[SELF] { self: SELF =>
  // worm saliva is actually quite pleasant
  def spitAt[A](a: SpittableAnimal[A]): a.SpatAt = a.asInstanceOf[A]
}
case class Worm() extends Vermiform[Worm]

object Test {
  def main(args: Array[String]) {
    val dog = Dog(anger = 0)
    val cat = Cat(anger = 0)
    val angryCat: Cat = dog spitAt cat // fine

    val anotherDog = Dog(0)
    val animals = Seq(dog, cat)
    val angryAnimals = for (a <- animals) yield anotherDog spitAt a
    val podAnimals = for (a <- angryAnimals) yield anotherDog spitAt a
    println(animals)
    println(angryAnimals)
    println(podAnimals)

    val worm = Worm()
    //println(worm spitAt dog) // Worms don't spit
  }
}
trait Excitable[T] { // TYPECLASS
  def withMoreAnger(t: T): T
}
trait Animal {
  type SpittableAnimal <: Animal
  def spitAt[A <: SpittableAnimal: Excitable](a: A): A
}
trait ExcitableAnimal extends Animal {
  type SpittableAnimal = ExcitableAnimal
  def spitAt[A <: SpittableAnimal: Excitable](a: A): A = implicitly[Excitable[A]] withMoreAnger a
}

object Dog {
  implicit object ExcitableDog extends Excitable[Dog] {
    def withMoreAnger(dog: Dog): Dog = dog copy (anger = dog.anger + 1)
  }
}
case class Dog(anger: Int) extends Quadruped

object Cat {
  implicit object ExcitableCat extends Excitable[Cat] {
    def withMoreAnger(cat: Cat): Cat = cat copy (anger = cat.anger + 1)
  }
}
case class Cat(anger: Int) extends Quadruped

sealed trait Quadruped extends ExcitableAnimal // sealed: to couple pattern match at implicit object ExcitableQuadruped and all subclasses of Quadruped
object Quadruped {
  implicit object ExcitableQuadruped extends Excitable[Quadruped] {
    def withMoreAnger(quadruped: Quadruped): Quadruped = {
      quadruped match {
        case dog: Dog => implicitly[Excitable[Dog]].withMoreAnger(dog)
        case cat: Cat => implicitly[Excitable[Cat]].withMoreAnger(cat)
      }
    }
  }
}

val dog = Dog(anger = 0)
val cat = Cat(anger = 0)
val angryCat: Cat = dog spitAt cat // fine
val anotherDog = Dog(0)
val animals: Seq[Quadruped] = Seq(dog, cat)
val angryAnimals: Seq[Quadruped] = for (a <- animals) yield anotherDog spitAt a // fine
val podAnimals: Seq[Quadruped] = for (a <- angryAnimals) yield anotherDog spitAt a // fine, still a Seq[Quadruped]