/ / "Kot łapie ptaka i je" - scala, niezmienność, cechy

"Kot łapie ptaka i je" - scala, niezmienność, cechy

"Scala in Depth" ma niezwykły przykład "Cat łapie ptaka i je". http://www.manning.com/suereth/Suereth_MEAP_CH01.pdf

trait Cat
trait Bird
trait Catch
trait FullTummy
def catch(hunter: Cat, prey: Bird): Cat with Catch
def eat(consumer: Cat with Catch): Cat with FullTummy
val story = (catch _) andThen (eat _)
story(new Cat, new Bird)

Moje pytania to:

  1. Pomijając część funkcjonalną, jak wyglądałyby wdrożenia?

  2. Czy jest to prawdziwa praktyka łącząca takie cechy, czy jest sztuczna? A co, jeśli w anonimowej klasie występuje 10 cech?

Moja implementacja (z pominiętą częścią funkcjonalną) wygląda następująco:

  case class Cat {
def catchIt(_prey: Bird): Cat with Catcher = {
new Cat with Catcher {
override val prey = _prey // This is ugly
}
}
}

case class Bird

trait WithFullTummy

trait Catcher {
val prey: Bird

def eat() = {
println(s"Ate the ${prey}")
new Cat with WithFullTummy
}
}

val cat = new Cat
val catWhoCaughtBird = cat.catchIt(new Bird)
catWhoCaughtBird.prey
val catWithFullTummy = catWhoCaughtBird.eat()

Odpowiedzi:

0 dla odpowiedzi № 1

(1.) Sądzę, że następujące rozwiązanie może być prostą implementacją.

trait Cat {
val catBreed: String
val name: String
}

trait Bird

trait Catch {
val prey: Bird
}

trait FullTummy {
val food: Bird
}

case class NastyCat(
val name: String,
val catBreed: String,
val prey: Bird) extends Cat with Catch

case class FullCat(
val name: String,
val catBreed: String,
val food: Bird) extends Cat with FullTummy

def catch(hunter: Cat, prey: Bird): Cat with Catch =
NastyCat(hunter.name, hunter.catBreed, prey)

def eat(consumer: Cat with Catch): Cat with FullTummy =
FullCat(consumer.name, consumer.catBreed, consumer.prey)

(2.) Tak, łączenie takich cech w celu określenia anonimowych typów powrotu może być bardzo użyteczne, oszczędza konieczności wypisywania cechy, która tylko rozszerza dwie inne cechy. Częściej widzisz kaczkę np. def eat[T <: { val food: Bird }](consumer: T). Kiedy liczba cech staje się duża, dla czytelności sake ludzie piszą tę cechę.