Free Monads

Recapitulación
Functor
Un funtor es un tipo F[A] con una operación map con el tipo (A => B) => F[B]
Funtor
Un funtor es un tipo F[A] con una operación map con el tipo (A => B) => F[B]
A F
Funtor
Un funtor es un tipo F[A] con una operación map con el tipo (A => B) => F[B]
A F
map
Funtor
Un funtor es un tipo F[A] con una operación map con el tipo (A => B) => F[B]
A F
map
val o = Option(1)
//o: Option[Int] = Some(1)
val f = ( i: Int ) => i + 1
//f: Int => Int
o.map( f )
//Option[Int] = Some(2)Mónada
Una mónada es un mecanismo de control para secuenciar cálculos
Mónada
Una mónada es un mecanismo de control para secuenciar cálculos
Una operación pure con tipo A => F[A]
Una operación flatMap con tipo (F[A], A => F[B]) => F[B]
Mónada
Una mónada es un mecanismo de control para secuenciar cálculos
import cats.Monad
import cats.instances.option._
Monad[Option].pure(1)
//Option[Int] = Some(1)Mónada
Una mónada es un mecanismo de control para secuenciar cálculos
val o = Some(1)
val f = ( i: Int ) => Some( i + 1 )
//f: Int => Some[Int]
o.flatMap( f )
//Option[Int] = Some(2)Mónada
Una mónada es un mecanismo de control para secuenciar cálculos
val o1 = Some(1)
val o2 = Some(2)
val r = for {
x <- o1
y <- o2
} yield x + y
//Option[Int] = Some(3)Transformación Natural
Transforma los valores de un tipo de primer orden, en otro tipo de primer orden
F[_], G[_]
Transformación Natural
Transforma los valores de un tipo de primer orden, en otro tipo de primer orden
F[_], G[_]
import cats.~>
val optionToList = new (Option ~> List) {
override def apply[A](fa: Option[A]): List[A] =
fa.toList
}
optionToList( Option(1) )
//List[Int] = List(1)DSL
DSL es un lenguaje específico del dominio. Contiene funciones que se refieren al dominio.
Free Monads
No fijar nuestras composiciones monádicas a un solo efecto sino como,
por el contrario, dejar el efecto libre y definirlo solo hasta el momento de la ejecución.
Separación entre la definición del programa (es decir, la lógica de negocio) y su implementación
Separación entre la definición del programa (es decir, la lógica de negocio) y su implementación
for {
n <- getUserName( id )
p <- getUserPhoto( id )
} yield User( n, p )def getUserName(userId: Long): UserName = ???
def getUserPhoto(userId: Long): Image = ???for {
n <- getUserName( id )
p <- getUserPhoto( id )
} yield User( n, p )def getUserName(userId: Long): UserName = ???
def getUserPhoto(userId: Long): Image = ???for {
n <- getUserName( id )
p <- getUserPhoto( id )
} yield User( n, p )import scala.language.higherKinds
trait Monad[F[_]] {
def pure[A](value: A): F[A]
def flatMap[A, B](value: F[A])(func: A => F[B]): F[B]
}def getUserName(userId: Long): UserNamecase class GetUserName(userId: Long) extends Service[UserName]Comenzamos creando un DSL
type UserName = String
type Image = String
sealed trait Service[A]
case class GetUserName(userId: Long) extends Service[UserName]
case class GetUserPhoto(userId: Long) extends Service[Image]// Eleva un F[A] en la mónada libre.
import cats.free.Free.liftF
def getUserName(userId: Long): ServiceF[UserName] = liftF( GetUserName( userId ) )
def getUserPhoto(userId: Long): ServiceF[Image] = liftF( GetUserPhoto( userId ) )import cats.free.Free
type ServiceF[A] = Free[Service, A]def getUser(id: Long) = for {
n <- getUserName( id )
p <- getUserPhoto( id )
} yield User( n, p )// Un intérprete requiere una mónada como parte final de la transformación
// ~> natural transformation
import cats.{Id, ~>}
object ServicePrinter extends (Service ~> Id) {
def apply[A](fa: Service[A]): Id[A] = fa match {
case GetUserName(userId) =>
println("GetUserName...")
"Mauricio"
case GetUserPhoto(userId) =>
println("GetUserPhoto...")
"=)"
}
}Nuestro primer intérprete
GetUserName...
GetUserPhoto...val res: Id[User] = getUser( 1 ).foldMap( ServicePrinter )
//res: Id[User] = User(Mauricio,=))import cats.{Id, ~>}
object ServiceUser extends (Service ~> Id) {
def apply[A](fa: Service[A]): Id[A] = fa match {
case GetUserName(userId) =>
"Mauricio"
case GetUserPhoto(userId) =>
"=)"
}
}Otro intérprete
Preguntas
FreeMonad
By maocq
FreeMonad
- 203