Generic case class instantiation

Hello, I’m having issues with implementation of collection to store continuous events.

The continuous event is something that happened in the past at startTime and and ended at endTime (or still continues). It is also possible that the exact time of the event is not known, in which case both startTime and endTime are None. The event has associated information of arbitrary type, it can be a string, a sequence of maps, etc. The goal of the collection is to implement logic of insertion of the events in the right order and do it as efficiently as possible.

Here is definition of an example event that extends the base class Event. You might wonder why there is a need for subclassing, the problem is that type of the additionalInfo must be known at compile time.

abstract class Event {
  def addedOn: Timestamp
  def startTime: Option[Timestamp]
  def endTime: Option[Timestamp]
  def additionalInfo: Any
}

case class StringEvent(
  intervalOpenness: Byte,
  startTime: Option[Timestamp],
  endTime: Option[Timestamp],
  additionalInfo: String)
    extends Event

Here is definition of the collection.

class Timeline[+A <: Event, +Repr] private (
    val history: Vector[A],
    val withReplacement: Boolean) extends Iterable[A]{

  def append[B >: A <: Event, That](e: B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
    // Determine the appropriate position for the event to be inserted
	// Find the neighbours and update the events using some rules
	// (for ex., when withReplacement = true update endTime of the previous event if it was the last event)
  }

  override def iterator: Iterator[A] = new AbstractIterator[A] {
    ...
  }
}

I was trying to follow an example from scala collections to define own. But I have a few problems I have no idea how to overcome:

  1. How to access fields of StringEvent inside append to determine right position for a new event? I added upper type bound on Event to achieve this, but I’m not sure how good this idea is;
  2. How to create a copy of a generic case class in order to update it? This part is the most frustrating, with abstract base class there is no method copy defined, so how to create an instance of Event with proper type is not clear.

I would appreciate any help. Thanks!

Not sure why you need the method additionalInfo of return type Any in Event. Are you going to pattern match the returned value? If so, probably better to pattern-match the Event object itself. Consider removing that method in Event or use a type parameter for the return type.

Not sure what the problem is regarding accessing the fields of StringEvent. After all, they are public. Or, do you mean the problem is that you don’t know that the type of an object is StringEvent? In that case, you either have to add more generic methods to Event that do what you want or pattern-match to determine whether it is a StringEvent.

Regarding copying, you can add your own method makeCopy to Event, but it is of limited usefulness. As a method of Event, the return type can only be Event or some type parameter. You would then, in every sub-class, specify the correct type by overriding or setting the type parameter, but still, when you have an object and all you know is that it is of type Event, then the return type of makeCopy still can only be Event. You can use pattern matching to check whether it is, for example, StringEvent, but then you can just create a new StringEvent without using a generic copy method.