Skip to content

Instantly share code, notes, and snippets.

@fserra-mdsol
Created December 12, 2024 20:59
Show Gist options
  • Save fserra-mdsol/7c9db0164d4ff799d1448bf52735ea7f to your computer and use it in GitHub Desktop.
Save fserra-mdsol/7c9db0164d4ff799d1448bf52735ea7f to your computer and use it in GitHub Desktop.
import cats.effect.*
object Hello extends App {
val x: Option[Int] = Some(1)
val y: List[Int] = List(1,2,3)
// Type constructor:
// Option[_]
// List[_]
// Set[_]
// Either[_, _]
// Future[_]
val x1 = x.map(_ + 1)
val y1 = y.map(_ + 1)
// .map ==> semantics of transformation
val x2 = x.flatMap(i => Option(i + 1))
val y2 = y.flatMap(i => List(i + 1))
val option1: Option[String] = Some("first")
val option2: Option[String] = Some("second")
val option3: Option[String] = Some("third")
val desugared = option1.flatMap(s => option2.map(x => s"$s-$x")).flatMap(y => option3.map(s => s"$y-$s"))
val desugaredMaps = option1.map(s => option2.map(x => s"$s-$x"))/*.map(y => option3.map(s => s"$y-$s"))*/
val desugaredMaps2 = x.map(i => i.toString)
val desugaredMaps3 = x.map(i => Right(i))
val desugared2 = option1.flatMap(first =>
option2.flatMap(second =>
option3.map(third =>
s"$first-$second-$third"
)
)
)
val sugared: Option[String] = for {
first <- option1
second <- option2
third <- option3
} yield { // this is where .map starts
s"$first-$second-$third"
}
// .flatMap ==> semantics of chaining and dependency
val either: Either[String, Int] = Right(1)
val either2: Either[String, Int] = Left("string")//Right(2)
val flatMappedEithers = either.flatMap(i => either2.map(x => i + x))
val left: Either[String, String] = Left("left")
val right: Either[String, String] = Right("right")
//val left1 = left.map(_ + "foo")
val right1 = right.map(_ + "foo").map(s => left.map(s1 => s + s1))
println(sugared)
println(desugared)
println(desugared2)
println(desugaredMaps)
println(desugaredMaps3)
println(flatMappedEithers)
println(right1)
println(x.map(identity))
//println(y2)
// .map => input is function that transforms the content of the container without transforming the container itself // A => B
// semantics of transformation
// .flatMap => input is a function that has to return the value wrapped in the same container type on which flatMap was called on // A => Option[B]
// semantics of chaining and dependency with transformation
def f(i: Int): Option[Int] = Option(i + 1)
val a = 2
val lhs = Option(a).flatMap(f)
val rhs = f(a)
println(lhs == rhs)
val m = Option(2)
val lhs1 = m.flatMap(Option(_))
val rhs1 = m
println(lhs1 == rhs1)
// Let f be a function that takes an Int and produces a List of its
// neighboring Ints along with itself:
val f1: (Int => List[Int]) = x => List(x - 1, x, x + 1)
// Let g be a function that takes an Int x
// and produces a List containing +x and -x
val g1: (Int => List[Int]) = x => List(x, -x)
val m1 = List(1, 2)
val lhs2 = m1.flatMap(f1).flatMap(g1)
val rhs2 = m1.flatMap(x => f1(x).flatMap(g1))
println(lhs == rhs)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment