object IntroSyntax { object HelloWorld extends App { println("Hello, world!") } def sendLetter(letter: String): Unit = ??? def greet(name: String = "World"): String = { s"Hello ${name}" } def writeLetter(): String = { val greeting = greet("Tux") s"""${greeting}, |Lorem ipsum. Et eius facilis praesentium |consectetur. Vitae aut nam maiores harum |omnis amet. Sint exercitationem vero |aliquam ipsam et deserunt.""".stripMargin } } object ExpressionsControlStructures { val PENGUIN_MAX_AGE: Int = 30 case class Penguin(age: Int) val tux = Penguin(21) val isTuxStillAlive: Bool = { val timeToLive = PENGUIN_MAX_AGE - tux.age val isAlive = if (timeToLive > 0) true else false isAlive } } object ExpressionsLoops { @tailrec def sumMultiplesOfThree(elems: Seq[Int], sum: Int = 0): Int = if (elems.isEmpty) sum else { val nextSum = sum + elem.head sumMultiplesOfThree(elems.tail, nextSum) } val sumOfThrees = sumMultiplesOfThree(elementList) object ListCombinators { class List[A] { def filter(func: (A) => Boolean): List[A] def foreach(func: (A) => Unit): Unit def map[B](func: (A) => B): List[B] def foldLeft[B](init: B)(func: (B, A) => B): B } } val elementList = 1 to 9 val sum = { var sum = 0 elementList.filter(i => i % 3 == 0).foreach(i => sum += i) sum } val sum = elementList.filter(i => i % 3 == 0).sum val sum = elementList.filter(_ % 3 == 0).sum val sum = elementList .filter(_ % 3 == 0) .foldLeft(0)((sum, nextElem) => sum + nextElem) } object ValVar { var a = 5 a = 3 a += 5 val b = 5 b = 3 // Fehler b += 5 // Fehler } object FirstClassFunctions { def sendRequestToIp( ip: String, req: Request): Response = ??? // in production val sendRequest = sendRequestToIp(config.serverIp, _) val res = doActualWork(sendRequest) def sendRequestToIp(ip: String, req: Request): Response = ??? def doActualWork(send: Request => Response): AwesomeResult = ??? // for tests val sendRequestForTesting = sendRequestToIp("127.0.0.1", _) val res = doActualWork(sendRequestForTesting) def sendRequestToIp(ip: String, req: Request): Response = ??? def doActualWork(send: Request => Response): AwesomeResult = ??? // for unittests def mockSendRequest(req: Request): Response = if (req == testCaseReq) testCaseResp else throw Exception() val res = doActualWork(mockSendRequest) } object Purity { def greet(name: String): String = s"Hello, ${name}" def greet(name: String): Unit = println(s"Hello, ${name}") def greet: String = s"Hello, ${getUserName()}" } object ADTAnatomie { case class ProductType(num: Int, ask: Bool) case class HttpResponse(status: Int, headers: Map[String, String], body: String) // Error is a sum type sealed trait Error case object Timeout extends Error case class UnknownStatusCode(statusCode: Int) extends Error case object BodyIsInvalidJSON extends Error def errorToMsg(err: Error): String = err match { case Timeout => "The server took too long to respond" case UnknownStatusCode(status) => s"The server returned an unknown status code of ${status}" case BodyIsInvalidJSON => "The response body was ill-formed JSON" } } object ADTOption { val PENGUIN_MAX_AGE: Int = 30 case class Penguin(age: Int) val penguinMap: Map[String, Penguin] = Map.empty object OptionDef { sealed trait Option[A] case class Some(value: A) extends Option[A] case object None extends Option } val penguinMap: Map[String, Penguin] val penguinOpt: Option[Penguin] = penguinMap.get(name) penguinOpt match { case Some(value) => println(s"The Option contains ${value}") case None => println(s"The Option is empty") } val timeToLive: Option[Int] = penguinOpt match { case Some(user) => val ttl: Int = PENGUIN_MAX_AGE - user.age Some(ttl) case None => None } val timeToLive = penguinMap.get(id).map(PENGUIN_MAX_AGE - _.age) } object ADTEither { object EitherDef { sealed trait Either[A, B] case class Left(value: A) extends Either case class Right(value: B) extends Either } def sendHttpRequest(req: HttpRequest): Either[Error, HttpResponse] val res = sendHttpRequest(HttpRequest(ip, endpoint, "GET")) val printMsg: String = res match { case Right(HttpResponse(respStatus, respBody)) => s"Status was ${respStatus} and the body is: ${respBody}" case Left(err) => errorToMsg(err) } } object ADTValidStates { trait AggroState case class Idle(aggroRadius: Float) extends AggroState case class Chasing(target: PlayerId, chaseTimer: Timer) extends AggroState case class Fighting(target: PlayerId) extends AggroState class MonsterAI (val aggroState: AggroState) } object ClassSyntaxCompanionObject { val url = "" case class HttpRequest(url: String, method: String, body: String) class Penguin(val name: String, given_age: Int) { var age: Int = given_age private var spouse: Option[Penguin] = None def marryTo(newSpouse: Penguin): Unit = spouse = Some(newSpouse) def timeToLive: Int = Penguin.MAX_AGE - age } object Penguin { val MAX_AGE = 30 def newBorn(name: String): Penguin = new Penguin(name, 0) def apply(name: String, given_age: Int): Penguin = new Penguin(name, given_age) } }