I've got an abstract class in scala:
abstract class Agent {
type geneType
val genome: Array[geneType]
implicit def geneTag: reflect.ClassTag[geneType]
def copy(newGenome: Array[geneType]): AgentT[geneType]
}
object Agent { type AgentT[A] = Agent { type geneType = A }}
I've also got an extension of that class:
case class Prisoner(initGenome: Array[Boolean]) extends Agent {
type geneType = Boolean
val genome = initGenome
def geneTag = implicitly[reflect.ClassTag[Boolean]]
def copy(newGenome: Array[geneType], memSize:Int):AgentT[Boolean] = new Prisoner(newGenome:Array[Boolean], memSize: Int)
}
I'd like to define a function that is parametrized by the geneType of an extension of Agent. I'm not sure how to access that type member of the class, though. Say it's the following function:
def slice[A](parentA: AgentT[A], parentB: AgentT[A]): (AgentT[A], AgentT[A]) = {
val genomeSize = parentA.genome.length
require (parentB.genome.length == genomeSize)
import parentA.geneTag
val index = (math.random * genomeSize + 0.5).toInt
val (aInit, aTail) = parentA.genome.splitAt(index)
val (bInit, bTail) = parentB.genome.splitAt(index)
val genomeA = Array.concat(aInit, bTail)
val genomeB = Array.concat(bInit, aTail)
(parentA.copy(genomeA), parentB.copy(genomeB))
}
Furthermore, say that this function is being called from within some other process, like this one:
abstract class Simulation[E <: Agent](population: Array[E]) {
var pop = population
// HERE's WHERE I'm CONFUSED
val (child1, child2) = slice[ ????????? ](pop(1), pop(2))
}
I was trying stuff like E.geneTag and E.geneType, and those didn't work. If I have an object of type Prisoner, I can access its geneType, Boolean, with
val pris = new Prisoner(genome, memSize)
pris.geneTag
But I'd like to access the geneTag associated with a type that extends Agent. I'd like to figure out how to do something like Prisoner.geneTag.
Any ideas?