1

[edit update] this is a proper statment of my problem.

I hope to call the constructor inside a trait. But it seems I have to use apply function. does it exist usage like new this()?

Like the code below. It throws type mismatch. I hope to add constraint of constructor, or I have to use apply function.

  trait B { this:C =>
    def values:Seq[Int]
    def apply(ints:Seq[Int]):this.type
    def hello:this.type = apply( values map (_ + 1) )
  }

  trait C

  class A(val v:Seq[Int]) extends C with B{
    override def values: Seq[Int] = v

    override def apply(ints: Seq[Int]): A.this.type = new A(ints)
  }
Mario Galic
  • 47,285
  • 6
  • 56
  • 98
worldterminator
  • 2,968
  • 6
  • 33
  • 52
  • it would be good to understand trait linearization order/rules. there is a good answer to explain that https://stackoverflow.com/a/34243727/1331769 – Vikas Pandya Sep 10 '19 at 14:46
  • 1
    @VikasPandya Issue here is not with linearization. It's just type mismatch. It's the same for both `C with B` and `B with C`. – Dmytro Mitin Sep 10 '19 at 14:54

1 Answers1

4

this.type is the type of this specific instance. So you can write

override def hello = this

but you can't write

override def hello = new A()

since A is a supertype of this.type.

Probably you wanted

trait B { this: C =>
  type This <: B /*or B with C*/
  def hello: This
}

trait C

class A extends C with B {
  type This = A
  override def hello = new A()
}

Or maybe even

trait B { self: C =>
  type This >: self.type <: B with C { type This = self.This }
  def hello: This
}

Returning the "Current" Type in Scala https://tpolecat.github.io/2015/04/29/f-bounds.html

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
  • I update the question, previous one doesn't reflect constructor. – worldterminator Sep 11 '19 at 12:14
  • @worldterminator Nothing changed. As I've already answered you can't assign a value of type `A` to a variable of type `A.this.type` since type `A` is a supertype of `A.this.type` and not vice versa. – Dmytro Mitin Sep 11 '19 at 13:08
  • is there any way to call constructor of A in trait? like this(params), I didn't find such syntax – worldterminator Sep 11 '19 at 13:22
  • @worldterminator You used proper syntax for constructor `new A(ints)`. `new this(params)` is illegal. `this(params)` is `this.apply(params)`. `new this(params)` is senseless, `this` is the only instanse. If you want new instance of `A` you should do `new A(params)`. You just can't assign this value to variable of type `A.this.type`. Type `A.this.type` is wrong here. – Dmytro Mitin Sep 11 '19 at 13:30
  • @worldterminator When you do `new A(ints)` you return `A`, not `A.this.type`. – Dmytro Mitin Sep 11 '19 at 13:35