Skip to content

Instantly share code, notes, and snippets.

@vaer-k
Last active November 14, 2018 19:11
Show Gist options
  • Save vaer-k/acf4e9342efc7c6422522426e705f877 to your computer and use it in GitHub Desktop.
Save vaer-k/acf4e9342efc7c6422522426e705f877 to your computer and use it in GitHub Desktop.
Intro to scala
{"paragraphs":[{"text":"%md\n\n### [Benefits of FP](https://alvinalexander.com/scala/fp-book/benefits-of-functional-programming#pure-functions-are-easier-to-reason-about)\n1. Pure functions are easier to reason about (referential transparency -> substitution model)\n2. Testing is easier, and pure functions lend themselves well to techniques like property-based testing\n3. Debugging is easier\n4. Programs are more bulletproof (immutability -> determinism)\n5. Programs are written at a higher level, and are therefore easier to comprehend\n6. Function signatures are more meaningful\n7. Parallel/concurrent programming is easier\n\n#### FP excels in:\n- Modularity \n- Reusability \n- Composability \n- Extensibility \n- Testability","user":"anonymous","dateUpdated":"2018-11-13T22:42:58+0000","config":{"colWidth":12,"fontSize":9,"enabled":true,"results":{},"editorSetting":{"language":"markdown","editOnDblClick":true,"completionKey":"TAB","completionSupport":false},"editorMode":"ace/mode/markdown","editorHide":true,"tableHide":false},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542145486517_1438791555","id":"20181113-214446_1488802087","dateCreated":"2018-11-13T21:44:46+0000","dateStarted":"2018-11-13T22:42:58+0000","dateFinished":"2018-11-13T22:42:58+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"focus":true,"$$hashKey":"object:27647"},{"title":"methods, type declarations, string interpolation, currying","text":"def userAbilityLogger(ability: String)(name: String): Unit = {\n println(s\"$name used $ability. It's super effective!\")\n}\n\nval userMeditationLogger = userAbilityLogger(\"meditation\")(_) // OR userAbilityLogger(\"meditation\")_ OR userAbilityLogger(\"meditation\") _\n\nuserAbilityLogger(\"webs\")(\"Peter Parker\")\nval userWebLogger = userAbilityLogger(\"webs\")_\nuserWebLogger(\"Peter Parker\")","user":"anonymous","dateUpdated":"2018-11-13T22:42:58+0000","config":{"lineNumbers":true,"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"colWidth":12,"editorMode":"ace/mode/scala","title":true,"results":{},"enabled":true,"fontSize":9},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542133034100_-1749450021","id":"20180926-201133_1380784591","dateCreated":"2018-11-13T18:17:14+0000","dateStarted":"2018-11-13T22:42:58+0000","dateFinished":"2018-11-13T22:43:22+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:27648"},{"title":"case classes, pattern matching","text":"// Prefer immutable data structures\ncase class User(id: Int, name: String)\n\n// Prefer val over var\nval user = User(5, \"Bruce Banner\")\nprintln(user.name)\n\nuser match {\n case User(uid, uname) if uname == \"Peter Parker\" => userAbilityLogger(\"webs\")(uname)\n case User(id, name) if name == \"Tony Stark\" => userAbilityLogger(\"monies and robots\")(name)\n case usr@User(_, name) if name == \"Bruce Banner\" => {\n userMeditationLogger(name)\n println(usr)\n }\n case _ => println(\"Nobody did anything. Nothing very effective happened.\")\n}","user":"anonymous","dateUpdated":"2018-11-13T22:43:22+0000","config":{"lineNumbers":true,"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"colWidth":12,"editorMode":"ace/mode/scala","title":true,"results":{},"enabled":true,"fontSize":9},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542133034104_-473668678","id":"20180926-200704_1011489711","dateCreated":"2018-11-13T18:17:14+0000","dateStarted":"2018-11-13T22:43:22+0000","dateFinished":"2018-11-13T22:43:24+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:27649"},{"text":"%md \n\n**Scala immutability - quotes from the experts**\n\na couple of quotes from Scala books. First, from Beginning Scala, by David Pollack:\n\n> “Using vals in your code makes you think about alternative, immutable, functional code. This small example demonstrates that removing vars leads to refactoring. The refactoring leads to new coding patterns. New coding patterns leads to a shift in your approach to programming. This shift in approach leads to transformative code that has fewer defects and is easier to maintain.”\n\nFrom the excellent book, Programming in Scala, by Odersky, Spoon, and Venners, there is a small section titled, “A balanced attitude for Scala programmers”:\n\n> “Prefer vals, immutable objects, and methods without side effects. Reach for them first. Use vars, mutable objects, and methods with side effects when you have a specific need and justification for them.”","user":"anonymous","dateUpdated":"2018-11-13T22:43:24+0000","config":{"tableHide":false,"editorSetting":{"language":"markdown","editOnDblClick":true,"completionSupport":false},"colWidth":12,"editorMode":"ace/mode/markdown","editorHide":true,"results":{},"enabled":true,"fontSize":9},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542133034104_-1014584337","id":"20180926-212302_776140708","dateCreated":"2018-11-13T18:17:14+0000","dateStarted":"2018-11-13T22:43:24+0000","dateFinished":"2018-11-13T22:43:24+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:27650"},{"title":"Polymorphism w/ type parameters","text":"type AbilityDB = Map[Int, String]\n\ndef getAbilityDB[A](a: List[A]): Map[Int, A] = {\n a.zipWithIndex.map({case (name, id) => (id, name)}).toMap\n}\n\nval nums = 1 to 10 toList\nval numberDB = getAbilityDB(nums)\n\nval abilities = List(\"webs\", \"'muricas\", \"monies and robots\", \"symbiotes\", \"meditation\", \"meditation\")\nimplicit val userAbilityDB: AbilityDB = getAbilityDB(abilities)","user":"anonymous","dateUpdated":"2018-11-13T22:43:24+0000","config":{"lineNumbers":true,"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"colWidth":12,"editorMode":"ace/mode/scala","title":true,"results":{},"enabled":true,"fontSize":9},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542133034105_-837345297","id":"20180926-231013_893792148","dateCreated":"2018-11-13T18:17:14+0000","dateStarted":"2018-11-13T22:43:24+0000","dateFinished":"2018-11-13T22:43:26+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:27651"},{"title":"Nulls are bad, mmkay?","text":"// BAD, but you can expect null return values when using spark/java libraries. How should we handle them?\ndef javaLibraryCall(user: User)(implicit userAbilityDB: AbilityDB): String = user match {\n case User(id, _) if scala.util.Random.nextInt(10) % 2 == 0 => userAbilityDB get id get\n case _ => null\n}\n\n// Note that supplying the DB as an implicit value here is unnecessary since it is already in lexical scope. This is a quirk of prototyping in Zeppelin, however, and in practice you will likely often find need to lean on implicits for clarity and convenience. You will absolutely find them in 3rd party libraries.","user":"anonymous","dateUpdated":"2018-11-13T22:43:26+0000","config":{"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"colWidth":12,"editorMode":"ace/mode/scala","title":true,"results":{},"enabled":true,"fontSize":9},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542133034105_-431968822","id":"20180926-194752_1836829877","dateCreated":"2018-11-13T18:17:14+0000","dateStarted":"2018-11-13T22:43:26+0000","dateFinished":"2018-11-13T22:43:26+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:27652"},{"text":"%md\n\nImplicit paramters and implicit conversion are **not** the same as type coercion. \n\nYes, type coercion is a process that executes implicitly in many languages, but the `implicit` keyword in scala is used to demarcate values are subjected to a process distinct from coercion and unique to Spark. Take the time to learn how this concept works, as you will see it used often.\n\n- [Implicit parameters](https://docs.scala-lang.org/tour/implicit-parameters.html)\n- [Implicit conversion](https://docs.scala-lang.org/tour/implicit-conversions.html)\n\n","user":"anonymous","dateUpdated":"2018-11-13T22:43:26+0000","config":{"colWidth":12,"fontSize":9,"enabled":true,"results":{},"editorSetting":{"language":"markdown","editOnDblClick":true,"completionKey":"TAB","completionSupport":false},"editorMode":"ace/mode/markdown","editorHide":true,"tableHide":false},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542144277039_1868248717","id":"20181113-212437_2127386542","dateCreated":"2018-11-13T21:24:37+0000","dateStarted":"2018-11-13T22:43:26+0000","dateFinished":"2018-11-13T22:43:26+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:27653"},{"title":"Options","text":"def getUserData(user: User): Option[String] = {\n Option(javaLibraryCall(user))\n}\n\ndef logUserData(user: User): Unit = {\n getUserData(user) match {\n case Some(ability) => userAbilityLogger(ability)(user.name)\n case None => None // Try commenting out this line\n }\n}","user":"anonymous","dateUpdated":"2018-11-13T22:43:26+0000","config":{"lineNumbers":true,"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"colWidth":12,"editorMode":"ace/mode/scala","title":true,"results":{},"enabled":true,"fontSize":9},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542133034105_-581240119","id":"20180926-200645_1459424943","dateCreated":"2018-11-13T18:17:14+0000","dateStarted":"2018-11-13T22:43:26+0000","dateFinished":"2018-11-13T22:43:27+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:27654"},{"text":"val u = User(2, \"Tony Stark\")\nlogUserData(u) // Handles the nulls swimmingly!","user":"anonymous","dateUpdated":"2018-11-13T23:45:39+0000","config":{"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"colWidth":12,"editorMode":"ace/mode/scala","results":{},"enabled":true,"fontSize":9,"lineNumbers":false},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542133034105_-376243301","id":"20180926-195815_841345338","dateCreated":"2018-11-13T18:17:14+0000","dateStarted":"2018-11-13T22:43:27+0000","dateFinished":"2018-11-13T22:43:27+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:27655"},{"user":"anonymous","config":{"colWidth":12,"fontSize":9,"enabled":true,"results":{},"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"editorMode":"ace/mode/scala","title":true,"lineNumbers":true},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542151577492_822278052","id":"20181113-232617_1440138308","dateCreated":"2018-11-13T23:26:17+0000","status":"FINISHED","progressUpdateIntervalMs":500,"focus":true,"$$hashKey":"object:29667","text":"val op1: Option[Double] = Some(2)\nval op2: Option[Double] = None\n\nval res1 = op1 map (_ + 1) map (_ * 2)\nval res2 = op2 map (_ + 1) map (_ * 2)\n\ndef loudHalve(x: Double): Double = {\n println(\"I'M HALVING NOW!!!!!\")\n x / 2\n}\n\nval res3 = op1 map (_ + 2) map (_ * 25) map loudHalve map (_ % 2) map (_ == 0) getOrElse false\nval res4 = op2.map(_ + 2).map(_ * 25).map(loudHalve).map(_ % 2).map(_ == 0).getOrElse(false)","dateUpdated":"2018-11-13T23:45:34+0000","dateFinished":"2018-11-13T23:38:30+0000","dateStarted":"2018-11-13T23:38:29+0000","title":"You do not need to take value out of its monadic option context until you need it","results":{"code":"SUCCESS","msg":[{"type":"TEXT","data":"op1: Option[Double] = Some(2.0)\nop2: Option[Double] = None\nres1: Option[Double] = Some(6.0)\nres2: Option[Double] = None\nloudHalve: (x: Double)Double\nI'M HALVING NOW!!!!!\nres3: Boolean = true\nres4: Boolean = false\n"}]}},{"title":"For loops: who are they for anyway?","text":"val heroesAndVillains = List(\"Peter Parker\", \"Steve Rogers\", \"Tony Stark\", \"Eddie Brock\", \"Bose Athota\", \"Bruce Banner\")\nheroesAndVillains.zipWithIndex.map({case (name, id) => User(id, name)}).foreach(logUserData)\n\n// filter, map and fold are your new best friends\n\n// Do use comprehensions\nval sums = for (i <- 0 until 10; // flatmap\n j <- i until 10 if i + j == 8) // map\n yield (i, j)","user":"anonymous","dateUpdated":"2018-11-13T22:43:27+0000","config":{"lineNumbers":true,"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"colWidth":12,"editorMode":"ace/mode/scala","title":true,"results":{},"enabled":true,"fontSize":9},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542133034105_1775662866","id":"20180926-210157_368563872","dateCreated":"2018-11-13T18:17:14+0000","dateStarted":"2018-11-13T22:43:27+0000","dateFinished":"2018-11-13T22:43:28+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:27656"},{"text":"case class PowerLevel(value: Int)\ncase class Ability(stats: Seq[PowerLevel])\ncase class Hero(abilities: Seq[Ability])\ncase class Team(heroes: List[Hero])\n\ndef getTeamValue(team: Team): Int = {\n\n val powersList = for {\n h <- team.heroes // flatmap\n a <- h.abilities // flatmap\n p <- a.stats // map\n } yield (p.value)\n\n powersList reduce (_ + _)\n}\n\n// values = []\n// for hero in team: \n// for ability in abilities:\n// for powerlevel in abilities:\n// values.append(powerlevel.value)\n\n// sum(values)\n\nval levels = 1 until 10 toList\nval powers = for (l <- levels) yield PowerLevel(l)\nval heroAbilities = for (_ <- 1 until 5) yield Ability(powers)\nval heroes = for (_ <- 1 until 5) yield Hero(heroAbilities)\nval avengers = Team(heroes.toList)\n\n// zeppelin fail: run in sbt instead\n// getTeamValue(avengers)","user":"anonymous","dateUpdated":"2018-11-13T23:45:44+0000","config":{"colWidth":12,"fontSize":9,"enabled":true,"results":{},"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"editorMode":"ace/mode/scala","tableHide":true,"lineNumbers":true},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542146672012_1896833634","id":"20181113-220432_621047513","dateCreated":"2018-11-13T22:04:32+0000","dateStarted":"2018-11-13T23:21:04+0000","dateFinished":"2018-11-13T23:21:07+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:27657","results":{"code":"SUCCESS","msg":[{"type":"TEXT","data":"defined class PowerLevel\ndefined class Ability\ndefined class Hero\ndefined class Team\ngetTeamValue: (team: Team)Int\nwarning: there was one feature warning; re-run with -feature for details\nlevels: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)\npowers: List[PowerLevel] = List(PowerLevel(1), PowerLevel(2), PowerLevel(3), PowerLevel(4), PowerLevel(5), PowerLevel(6), PowerLevel(7), PowerLevel(8), PowerLevel(9))\nheroAbilities: scala.collection.immutable.IndexedSeq[Ability] = Vector(Ability(List(PowerLevel(1), PowerLevel(2), PowerLevel(3), PowerLevel(4), PowerLevel(5), PowerLevel(6), PowerLevel(7), PowerLevel(8), PowerLevel(9))), Ability(List(PowerLevel(1), PowerLevel(2), PowerLevel(3), PowerLevel(4), PowerLevel(5), PowerLevel(6), PowerLevel(7), PowerLevel(8), PowerLevel(9))), Ability(List(PowerLevel(1), PowerLevel(2), PowerLevel(3), PowerLevel(4), PowerLevel(5), PowerLevel(6), PowerLevel(7), PowerLevel(8), PowerLevel(9))), Ability(List(PowerLevel(1), PowerLevel(2), PowerLevel(3), PowerLevel(4), PowerLevel(5), PowerLevel(6), PowerLevel(7), PowerLevel(8), PowerLevel(9))))\nheroes: scala.collection.immutable.IndexedSeq[Hero] = Vector(Hero(Vector(Ability(List(PowerLevel(1), PowerLevel(2), PowerLevel(3), PowerLevel(4), PowerLevel(5), PowerLevel(6), PowerLevel(7), PowerLevel(8), PowerLevel(9))), Ability(List(PowerLevel(1), PowerLevel(2), PowerLevel(3), PowerLevel(4), PowerLevel(5), PowerLevel(6), PowerLevel(7), PowerLevel(8), PowerLevel(9))), Ability(List(PowerLevel(1), PowerLevel(2), PowerLevel(3), PowerLevel(4), PowerLevel(5), PowerLevel(6), PowerLevel(7), PowerLevel(8), PowerLevel(9))), Ability(List(PowerLevel(1), PowerLevel(2), PowerLevel(3), PowerLevel(4), PowerLevel(5), PowerLevel(6), PowerLevel(7), PowerLevel(8), PowerLevel(9))))), Hero(Vector(Ability(List(PowerLevel(1), PowerLevel(2), PowerLevel(3), PowerLevel(4), PowerLevel(5), PowerLevel(6), PowerLe...avengers: Team = Team(List(Hero(Vector(Ability(List(PowerLevel(1), PowerLevel(2), PowerLevel(3), PowerLevel(4), PowerLevel(5), PowerLevel(6), PowerLevel(7), PowerLevel(8), PowerLevel(9))), Ability(List(PowerLevel(1), PowerLevel(2), PowerLevel(3), PowerLevel(4), PowerLevel(5), PowerLevel(6), PowerLevel(7), PowerLevel(8), PowerLevel(9))), Ability(List(PowerLevel(1), PowerLevel(2), PowerLevel(3), PowerLevel(4), PowerLevel(5), PowerLevel(6), PowerLevel(7), PowerLevel(8), PowerLevel(9))), Ability(List(PowerLevel(1), PowerLevel(2), PowerLevel(3), PowerLevel(4), PowerLevel(5), PowerLevel(6), PowerLevel(7), PowerLevel(8), PowerLevel(9))))), Hero(Vector(Ability(List(PowerLevel(1), PowerLevel(2), PowerLevel(3), PowerLevel(4), PowerLevel(5), PowerLevel(6), PowerLevel(7), PowerLevel(8), PowerLevel(..."}]}},{"title":"Failure handling","text":"def getEven(x: Int): Either[String, Int] = {\n x match {\n case x if x % 2 == 0 => Right(x)\n case _ => Left(\"That thing aint even even.\")\n }\n}\n\ndef checkEven(x: Int): Unit = {\n getEven(x) match {\n case Left(msg) => println(msg)\n case Right(_) => println(\"So beautifully even.\")\n }\n}","user":"anonymous","dateUpdated":"2018-11-13T22:43:30+0000","config":{"lineNumbers":true,"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"colWidth":12,"editorMode":"ace/mode/scala","title":true,"results":{},"enabled":true,"fontSize":9},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542133034106_-997336170","id":"20180926-202621_416073814","dateCreated":"2018-11-13T18:17:14+0000","dateStarted":"2018-11-13T22:43:30+0000","dateFinished":"2018-11-13T22:43:31+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:27658"},{"text":"checkEven(2)\ncheckEven(3)","user":"anonymous","dateUpdated":"2018-11-13T22:43:31+0000","config":{"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"colWidth":12,"editorMode":"ace/mode/scala","results":{},"enabled":true,"fontSize":9},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542133034106_-1490080459","id":"20180926-205303_1331625290","dateCreated":"2018-11-13T18:17:14+0000","dateStarted":"2018-11-13T22:43:31+0000","dateFinished":"2018-11-13T22:43:31+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:27659"},{"title":"Either or Option","text":"%md\n\nIf you only use an Either exactly like an imperative try-catch block, of course it's going to look like different syntax to do exactly the same thing. Eithers are a value. They don't have the same limitations. You can:\n\n- Stop your habit of keeping your try blocks small and contiguous. The \"catch\" part of Eithers doesn't need to be right next to the \"try\" part. It may even be shared in a common function. This makes it much easier to separate concerns properly.\n- Store Eithers in data structures. You can loop through them and consolidate error messages, find the first one that didn't fail, lazily evaluate them, or similar.\n- Extend and customize them. Don't like some boilerplate you're forced to write with Eithers? You can write helper functions to make them easier to work with for your particular use cases. Unlike try-catch, you are not permanently stuck with only the default interface the language designers came up with.\n\nAn Option is even simpler if all you care about is success or failure and don't need any state information like error messages about the failure case.","user":"anonymous","dateUpdated":"2018-11-13T22:43:31+0000","config":{"tableHide":false,"editorSetting":{"language":"markdown","editOnDblClick":true},"colWidth":12,"editorMode":"ace/mode/markdown","editorHide":true,"title":true,"results":{},"enabled":true,"fontSize":9},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542133034106_-1771837727","id":"20180926-205430_919732041","dateCreated":"2018-11-13T18:17:14+0000","dateStarted":"2018-11-13T22:43:31+0000","dateFinished":"2018-11-13T22:43:31+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:27660"},{"text":"def getUserDataEither(user: User): Either[String, String] = {\n Option(javaLibraryCall(user)) match {\n case None => Left(s\"nothing very effective happened.\")\n case Some(ability) => Right(ability)\n }\n}\n\ndef logUserDataEither(user: User): Unit = {\n val name = user.name\n getUserDataEither(user) match {\n case Left(message) => {\n print(s\"$name tried super hard, but \")\n print(message ++ \"\\n\")}\n case Right(ability) => userAbilityLogger(ability)(user.name)\n }\n}\n\nheroesAndVillains.zipWithIndex map {case (name, id) => User(id, name)} foreach logUserDataEither","user":"anonymous","dateUpdated":"2018-11-13T22:44:59+0000","config":{"lineNumbers":true,"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"colWidth":12,"editorMode":"ace/mode/scala","results":{},"enabled":true,"fontSize":9},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542133034106_882870267","id":"20180926-213835_490277457","dateCreated":"2018-11-13T18:17:14+0000","dateStarted":"2018-11-13T22:44:59+0000","dateFinished":"2018-11-13T22:45:00+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:27661"},{"title":"Exception handling","text":"import scala.util.{Try,Success,Failure}\n\ndef networkCall(user: User): String = user match {\n case User(id, _) if scala.util.Random.nextInt(10) % 2 == 0 => userAbilityDB get id get\n case _ => throw new Exception(s\"WARNING: ${user.name} could not acquire an ability.\")\n}\n\ndef getUserDataTry(user: User): Try[String] = Try(networkCall(user))\n\ndef logUserDataTry(user: User): Unit = {\n getUserDataTry(user) match {\n case Success(ability) => userAbilityLogger(ability)(user.name)\n case Failure(e) => println(e)\n }\n}\n\nheroesAndVillains.zipWithIndex.map({case (name, id) => User(id, name)}).foreach(logUserDataTry)","user":"anonymous","dateUpdated":"2018-11-13T23:45:50+0000","config":{"colWidth":12,"editorMode":"ace/mode/scala","results":{},"enabled":true,"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"fontSize":9,"title":true,"lineNumbers":true},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542133034107_1200218823","id":"20181002-214024_1632607237","dateCreated":"2018-11-13T18:17:14+0000","dateStarted":"2018-11-13T22:44:52+0000","dateFinished":"2018-11-13T22:44:53+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:27662"},{"user":"anonymous","config":{"colWidth":12,"fontSize":9,"enabled":true,"results":{},"editorSetting":{}},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1542150778052_991751926","id":"20181113-231258_1711086975","dateCreated":"2018-11-13T23:12:58+0000","status":"READY","progressUpdateIntervalMs":500,"focus":true,"$$hashKey":"object:29231"}],"name":"lessons/Lessons in Scala","id":"2DWAEU7NV","noteParams":{},"noteForms":{},"angularObjects":{"md:shared_process":[],"spark:shared_process":[]},"config":{"isZeppelinNotebookCronEnable":false,"looknfeel":"default","personalizedMode":"false"},"info":{}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment