diff --git a/src/main/scala/training/Program.scala b/src/main/scala/training/Program.scala index 9e7fb58..f4d5906 100644 --- a/src/main/scala/training/Program.scala +++ b/src/main/scala/training/Program.scala @@ -8,13 +8,16 @@ object Program extends App { case class Account(id: String, balance: Int) case class Statement(isRich: Boolean, accounts: Int) - def getBalanceBank1: Maybe[Account] = Yes(Account("a1", 100)) + def getBank1Credentials: Maybe[String] = Yes("MyUser_MyPassword") + + def getBalanceBank1(credentials: String): Maybe[Account] = Yes(Account("a1", 100)) def getBalanceBank2: Maybe[Int] = Yes(80) val moneyInPocket: Int = 20 - val b1: Maybe[Int] = getBalanceBank1.map(_.balance) + val c: Maybe[String] = getBank1Credentials + val b1: Maybe[Int] = getBank1Credentials.flatMap(cred => getBalanceBank1(cred).map(_.balance)) val b2: Maybe[Int] = getBalanceBank2 val p: Maybe[Int] = moneyInPocket.pure diff --git a/src/main/scala/training/implicits.scala b/src/main/scala/training/implicits.scala index 3049acb..1550284 100644 --- a/src/main/scala/training/implicits.scala +++ b/src/main/scala/training/implicits.scala @@ -16,6 +16,8 @@ object implicits { implicit def maybeLifter: Lifter[Maybe] = new MaybeLifter + implicit def maybeFlattener: Flattener[Maybe] = new MaybeFlattener + //Syntax implicit class CombinatorSyntax[A](self: Maybe[A]) { @@ -30,4 +32,8 @@ object implicits { def pure[F[_]](implicit ev: Lifter[F]): F[A] = ev.pure(self) } + implicit class FlattenerSyntax[A](self: Maybe[A])(implicit ev: Flattener[Maybe]){ + def flatMap[B](f: A => Maybe[B]): Maybe[B] = ev.flatMap(self, f) + } + } diff --git a/src/main/scala/training/instances.scala b/src/main/scala/training/instances.scala index 1f53f72..da4e09d 100644 --- a/src/main/scala/training/instances.scala +++ b/src/main/scala/training/instances.scala @@ -38,5 +38,12 @@ object instances { override def pure[A](a: A): Maybe[A] = Maybe(a) } + class MaybeFlattener extends Flattener[Maybe] { + override def flatMap[A, B](fa: Maybe[A], f: A => Maybe[B]): Maybe[B] = fa match { + case Yes(a) => f(a) + case No => No + } + } + } diff --git a/src/main/scala/training/typeclasses.scala b/src/main/scala/training/typeclasses.scala index 58e19be..deb25a8 100644 --- a/src/main/scala/training/typeclasses.scala +++ b/src/main/scala/training/typeclasses.scala @@ -25,5 +25,9 @@ object typeclasses { def pure[A](a: A): F[A] } + trait Flattener[F[_]]{ + def flatMap[A, B](fa: F[A], f: A => F[B]): F[B] + } + }