Skip to content

Instantly share code, notes, and snippets.

@gustavofranke
Last active September 30, 2019 18:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gustavofranke/512690839e2963545912123fc3298f32 to your computer and use it in GitHub Desktop.
Save gustavofranke/512690839e2963545912123fc3298f32 to your computer and use it in GitHub Desktop.
package tasks.option
import org.scalatest.FunSuite
/**
* show some scala stuff that I found weird when I started this journey
*
* I'll use scala test as a vehicle,
* but this is not a talk about writing tests, so the tests themselves will be a little repetitive.
* I'll be using a very basic subset of the library, the library has lots of features.
*
* Pattern matching could be used as kinda like a switch statement, although that's not how it's aimed to be used.
*/
class PatternSuite extends FunSuite {
test("match or not") {
val a = 5 match {
case 1 => "one";
case 5 => "five"
}
assert(a === "five")
}
test("match boom!") {
assertThrows[scala.MatchError] {
5 match {
case 1 => "one";
case 4 => "four"
}
}
assertThrows[scala.MatchError] {
"yes" match {
case "y" => 1;
case "n" => 0
}
}
}
test("match boom! - there, I fixed it") {
val a = 2 match {
case 1 => "one";
case 5 => "five";
case _ => "none of them"
}
assert(a === "none of them")
}
}
/**
* In the functional-scala talk, we discussed intuitions for the concepts of
* 1. type
* 2. product => tuple
* 3. co-product => ADT, GADT
*
* But in reality,
* pattern matching is aimed to traverse an entire ADT hierarchy (at the type level,
* as opposed to at the value level)
*/
class ADTSuite extends FunSuite {
sealed trait Status
case object Active extends Status
case object Inactive extends Status
def toNumber(s: Status): Int = s match {
case Active => 1
case Inactive => 2
}
test("asdfdsa") {
val a: Status = Active
val b: Status = Inactive
assert(toNumber(a) === 1)
assert(toNumber(b) === 2)
}
}
class OptionSuite extends FunSuite {
test("basic get happy path") {
val a = Some(5)
assert(a.get === 5)
}
test("basic get unhappy path") {
assertDoesNotCompile(
"""
| val a: Option[Int] = None
|a.get === 5
""".stripMargin)
}
test("happy path") {
val a = Some(5)
assert(a.map(x => x + 1) === Some(6))
}
test("unhappy path") {
val a: Option[Int] = None
assert(a.map(x => x + 1) === None)
}
test("need to flatten") {
val a = Some(5)
assert(a.map(x => Some(x + 1)) === Some(Some(6)))
}
test("flatten! happy path") {
val a: Option[Int] = None
assert(a.flatMap(x => Some(x + 1)) === None)
}
test("flatten!") {
val a = Some(5)
assert(a.flatMap(x => Some(x + 1)) === Some(6))
}
test("combine 2 somes with for comprehension") {
val a = for {
b <- Some(3)
c <- Some(2)
} yield b + c
assert(a === Some(5))
}
test("combine 1 some and 1 none with for comprehension") {
val none: Option[Int] = None
val a = for {
b <- none
c <- Some(2)
} yield b + c
assert(a === None)
}
test("dissect a for comprehension with previously used values (2 somes)") {
val a = Some(3).flatMap(b =>
Some(2).map(c =>
b + c)
)
assert(a === Some(5))
}
test("dissect a for comprehension with previously used values (1 some and 1 none)") {
val none: Option[Int] = None
val a = none.flatMap(b =>
Some(2).map(c =>
b + c)
)
assert(a === None)
}
}
/**
* in the effects talk,
* we explored a model for computations that allow us to come up with concepts for some common effects
*
* If we stick to one of them, we can see a lot of language features in action
*
* pattern matching
* generics
* variance
* HOFs
* co-product or sum type, ADT, GADT
* botton type
*/
sealed trait Option[+A] {
def map[B](f: A => B): Option[B] = this match {
case None => None
case Some(s) => Some(f(s))
}
def flatMap[B](f: A => Option[B]): Option[B] = map(f).getOrElse(None)
def getOrElse[B >: A](default: B): B = this match {
case None => default
case Some(s) => s
}
def filter(f: A => Boolean): Option[A] = flatMap(s => if (f(s)) Some(s) else None)
}
case object None extends Option[Nothing]
case class Some[+A](get: A) extends Option[A]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment