Untitled

 avatar
unknown
plain_text
4 years ago
3.0 kB
6
Indexable
package daniel.test

object Main {
  def main(args: Array[String]): Unit = {
    import TellMeMore._
    val strings = Seq("jed", "dwa", "trzy")
    val ints = List(1, 2, 4, 5, 6)

    val res = for {
      s <- strings
      i <- ints
    } yield s"$s $i"
    println(res)

    val sameRes = strings.flatMap(s => ints.map(i => s"$s $i"))
    println(sameRes)


    // type class
    val x = Test("mordo")
    println(TellMeMore.tellMeMoreMethod(x))
    x.tellingYouSomething


    // type bound
    val schowekNaBmx = new SchowekRowerowy[Bmx](new Bmx)
//    val schowekNaSamochod = new SchowekRowerowy[Samochod](new Samochod)
    val schowekNaCan = new SchowekCanyonMTB[CanyonMtb](new CanyonMtb)


    // variance
    // List are List[+A]
    def printAnimalNames(animals: List[Animal]): Unit =
      animals.foreach {
        animal => println(animal.name)
      }

    val cats: List[Cat] = List(Cat("Whiskers"), Cat("Tom"))
    val dogs: List[Dog] = List(Dog("Fido"), Dog("Rex"))

    // prints: Whiskers, Tom
    printAnimalNames(cats)

    // prints: Fido, Rex
    printAnimalNames(dogs)


    def printMyCat(printer: Printer[Cat], cat: Cat): Unit =
      printer.print(cat)

    val catPrinter: Printer[Cat] = new CatPrinter
    val animalPrinter: Printer[Animal] = new AnimalPrinter

    printMyCat(catPrinter, Cat("Boots"))
    printMyCat(animalPrinter, Cat("Boots"))
//    printMyCat(animalPrinter, Dog("Boots"))





  }
}


// variance
abstract class Animal {
  def name: String
}
case class Cat(name: String) extends Animal
case class Dog(name: String) extends Animal

abstract class Printer[-A] {
  def print(value: A): Unit
}

class AnimalPrinter extends Printer[Animal] {
  def print(animal: Animal): Unit =
    println("The animal's name is: " + animal.name)
}

class CatPrinter extends Printer[Cat] {
  def print(cat: Cat): Unit =
    println("The cat's name is: " + cat.name)
}


// type bound
abstract class Pojazd {
  def name: String
}

abstract class Rower extends Pojazd {}

class Bmx extends Rower {
  override def name: String = "Bmx"
}

class Mtb extends Rower {
  override def name: String = "Mtb"
}

class CanyonMtb extends Mtb {
  override def name: String = "CanyonMtb"
}

class CanyonMtbDuze extends Mtb {
  override def name: String = "CanyonMtbDuze"
}


class Samochod extends Pojazd {
  override def name: String = "Samochod"
}

class SchowekRowerowy[P <: Rower](p: P) {
  def pet: P = p
}

class SchowekCanyonMTB[P >: CanyonMtb <: Mtb](p: P) {
  def pet: P = p
}



// type class
case class Test(s: String)

trait TellMeMore[A] {
  def tellingMore(arg: A): String
}

object TellMeMore {

  def tellMeMoreMethod[A](arg: A)(implicit tellMeMore: TellMeMore[A]): String = {
    tellMeMore.tellingMore(arg)
  }

  implicit val testTeller: TellMeMore[Test] = new TellMeMore[Test] {
    override def tellingMore(arg: Test): String = arg.s
  }

  implicit class TellMeMoreOps[A](value: A) {
    def tellingYouSomething(implicit tellMeMore: TellMeMore[A]): String = {
      tellMeMore.tellingMore(value)
    }
  }
}

Editor is loading...