Scala higher type syntax

I am new to Scala and new to higher types. I want to write something like this:

trait Actor[E[Dependency] <: Event[Dependency]] {
  def execute(dependency: Dependency): Unit
}

However, I cannot refer to a parameter of type Dependency in the execute method - the compiler does not know it.

I know that I can solve this as follows without HKT, but this is not the issue in question;

trait Actor[T <: Event[Dependency], Dependency] {
   def execute(dependency: Dependency): Unit
}

I would like to understand why it does not work with the higher grade syntax that I tried? Is it even possible to express this with HKT? Is this a valid use case for HKT?


EDIT

A little more information, the event is as follows:

trait Event[Data] {
   val payload: Data
}

... and I'm looking for a definition of an event and such an actor,

case class FooEvent(payload: Foo) extends Event[Foo]

class FooActor extends Actor[FooEvent] {
   def execute(dependency: Foo) = {}
}
+4
source share
2 answers

- , . , HKT, , .

E[Dependency] E[_], , E . , Dependency . E E[Dependency] . E , E[Dependency] , . ,

trait Actor[E[D] <: Event[D]] { def execute(d: E) {} }

trait Actor[E[D] <: Event[D]] { def execute(d: E[D]) {} }

.

:

trait Actor[E[D] <: Event[D]] { def execute[B](d: E[B]) {} }

E[B] - .

:

, :

  trait Event[P] {
    val payload: P
  }

  case class FooEvent(payload: Int) extends Event[Int]

  trait BaseActor {
    type E = Event[P]
    type P
    def execute(dep: P)
    def runEvent(event: E)
  }

  trait IntActor extends BaseActor {
    type P = Int
  }

  class FooActor extends IntActor {
    def execute(dependency: P) = {}
    def runEvent(event: E) = {}
  }

  val c = new FooActor()
  c.runEvent(FooEvent(5))
  c.execute(5)

, type P, Dependency type E = Event[P], Event[Dependency], , P E, . , , . , IntActor . ,

+3

Dependency execute - .

, Actor.

val actor = new Actor[Event] // E is Event
actor.execute(???) // what argument is this supposed to take? I.e. what is Dependency for Actor[Event]?

: [Dependency, T <: Event[Dependency]] - , . Actor[E[Dependency] <: Event[Dependency]], , E . FooEvent , Actor[FooEvent] .

2: :

trait Event {
  type Dependency
  val payload: Dependency
}

trait Actor {
  type E <: Event

  def execute(e: E#Dependency)
}

class Foo

case class FooEvent(payload: Foo) extends Event {
  type Dependency = Foo
}

class FooActor extends Actor {
  type E = FooEvent

  def execute(e: Foo) = {}
}
+2

Source: https://habr.com/ru/post/1609134/


All Articles