This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val IOoOption = compose[IO, Option] | |
// Using cats: | |
// val IOoOption = Applicative[IO].compose[Option] | |
val user: IO[Option[User]] = | |
IOoOption.map2(getName2(userId), getAddress2(userId))(User.apply) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cats._, cats.implicits._, cats.effect.IO | |
// No details about any specific applicative functor | |
def compose[F[_]: Applicative, G[_]: Applicative](): Applicative[Lambda[l => F[G[l]]]] = { | |
val AF = Applicative[F] | |
val AG = Applicative[G] | |
new Applicative[Lambda[l => F[G[l]]]] { | |
override def pure[A](a: A): F[G[A]] = AF.pure(AG.pure(a)) | |
override def ap[A, B](ff: F[G[A => B]])(fa: F[G[A]]): F[G[B]] = |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cats._, cats.implicits._, cats.effect.IO | |
// Adds two numbers together (curried) | |
val add = (x: Int) => (y: Int) => x + y | |
// Example using the ap function for list | |
val A1: List[Int => Int] = List(1,2).map(add) // map comes from the functor typeclass | |
val result1: List[Int] = Applicative[List].ap(A1)(List(4,5)) // List[Int](5,6,6,7) | |
// Example using the ap function for IO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Old version | |
// def getName(id: Long): IO[Name] = /* Call third party API */ | |
// def getAddress(id: Long): IO[Address] = /* Call third party API */ | |
// The return type is now IO[Option[_]] | |
def getName(id: Long): IO[Option[Name]] = /* Call third party API */ | |
def getAddress(id: Long): IO[Option[Address]] = /* Call third party API */ | |
val userId = 100L |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Applicative functor version | |
val user: IO[User] = Applicative[IO].map2(getName(userId), getAddress(userId))(User.apply) | |
// Alterntive version with mapN on tupleN | |
val user: IO[User] = (getName(userId), getAddress(userId)).mapN(User.apply) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val user: IO[User] = for { | |
name <- getName(userId) | |
address <- getAddress(userId) | |
} yield User(name, address) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cats._, cats.implicits._, cats.effect.IO | |
case class Name(firstName: String, lastName: String) | |
case class Address(street: String, zip: String, state: String) | |
case class User(name: Name, address: Address) | |
def getName(id: Long): IO[Name] = /* Call third party API */ | |
def getAddress(id: Long): IO[Address] = /* Call third party API */ | |
val userId = 100L |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Monad version | |
for { | |
firstName <- Some("Bob") | |
lastName <- Some("Axel") | |
} yield firstname + " " + lastName // Some("Bob Axel") | |
// Applicative functor version | |
Applicative[Option].map2(Some("Bob"), Some("Axel"))((a,b) => a + " " + b) // Some("Bob Axel") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait Applicative[F[_]] extends Functor[F] { | |
def pure[A](x: A): F[A] | |
def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] | |
def map2[A, B, Z](fa: F[A], fb: F[B])(f: (A, B) => Z): F[Z] = | |
ap(map(fa)(a => (b: B) => f(a,b)))(fb) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait Applicative[F[_]] extends Functor[F] { | |
def pure[A](x: A): F[A] | |
def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] | |
} |
NewerOlder