/ / "Kočka uloví a žije vták" - scala, nezmeniteľnosť, znaky

"Kočka uloví vták a jedie ho" - scala, nezmeniteľnosť, črty

"Scala in Depth" má nezvyčajný príklad: "Kočka uloví vták a jedie ho". 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 otázky sú:

  1. Zanedbanie funkčnej časti, aké by vyzerali implementácie?

  2. Je skutočnou praxou spojiť tieto vlastnosti, alebo je to umelé? Čo ak má 10 znakov, ktoré je možné kombinovať v anonymnej triede?

Moja implementácia (s vynechanou funkčnou časťou) vyzerá takto:

  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()

odpovede:

0 pre odpoveď č. 1

(1.) Myslím si, že nasledovné by mohlo byť jednoduchou implementáciou.

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.) Áno, kombinácia takýchto vlastností určuje anonymný návrat. Typy môžu byť veľmi užitočné, šetria sa tým, že sa musí napísať vlastnosť, že všetko, čo robí, rozširuje ďalšie dva znaky. Častejšie vidíte typovanie kačice napr. def eat[T <: { val food: Bird }](consumer: T), Keď sa počet znakov stane veľký, ľudia by čitateľne napísali vlastnosť.