With the code below, I would like to make the following things :
// ... create an group using the "and" keyword
new Lion() and new Dog() and new Cat()
// a group could contain also only one animal
// have a modify method that takes arbitrary number of modifier with a "and" keyword
new Lion() modify SomethingFun("HELLO") and SomethingFun("WORD")
// understood as ( new Lion() ) modify ( SomethingFun("HELLO") and SomethingFun("WORD") )
Using implicit conversions described in the scala tour https://docs.scala-lang.org/tour/implicit-conversions.html and type inference ( for example , the PetModifiers of type Cat could not apply modification on Lion). Thanks for your help
trait Animal {
var name: String
def name(newString : String) { this.name = newString }
}
class Cat extends Animal {
override var name: String = "Cat"
}
class Dog extends Animal {
override var name: String = "Dog"
}
class Lion extends Animal {
override var name: String = "Lion"
}
trait PetModifier[ApplyOn <: Animal] {
def change(x: ApplyOn): Unit
}
case class SomethingFun(s: String) extends PetModifier[Animal] {
override def change(x: Animal): Unit = {
x.name(x + " " + s)
}
}
class Group[P <: Animal](pets: Stream[P]) extends Iterable[P] {
// operations : foreach / map / flatmap
override def iterator = pets.iterator
def and[B >: P <: Animal](element : B) = {
new Group(
Stream.consWrapper(pets).#::(element)
)
}
}
class Modifiers[+T](modifiers: => Stream[T]) {
def and[B <: PetModifier[_]](mod: B) = {
new Modifiers(
Stream.consWrapper(modifiers).#::(mod)
)
}
// a iterator to get access to element
def iterator = modifiers.iterator
}