How to stop execution in for-comprehension if Option is None using cats IO?











up vote
6
down vote

favorite
1












If i just use Option in for-comprehension everything goes as expected:



val a = Some(1)
val b = None
val c = Some(3)

val r = for {
aa <- a
bb <- b
cc <- c
} yield aa + bb + cc

println(r) // None, because b is None


but how to achieve the same behaviour using cats IO?



import cats.effect.IO
// in reality this will be a methods with side effect
val a = Some(1)
val b = None
val c = Some(3)

val r = for {
_ <- IO{println("a"); a}
_ <- IO{println("b"); b} // want to stop execution here
_ <- IO{println("c"); c}
} yield ()

r.unsafeRunSync()


In result i get a b c, but i expect only a b.



Is it possible to achieve? Is it a right way to do it?










share|improve this question




























    up vote
    6
    down vote

    favorite
    1












    If i just use Option in for-comprehension everything goes as expected:



    val a = Some(1)
    val b = None
    val c = Some(3)

    val r = for {
    aa <- a
    bb <- b
    cc <- c
    } yield aa + bb + cc

    println(r) // None, because b is None


    but how to achieve the same behaviour using cats IO?



    import cats.effect.IO
    // in reality this will be a methods with side effect
    val a = Some(1)
    val b = None
    val c = Some(3)

    val r = for {
    _ <- IO{println("a"); a}
    _ <- IO{println("b"); b} // want to stop execution here
    _ <- IO{println("c"); c}
    } yield ()

    r.unsafeRunSync()


    In result i get a b c, but i expect only a b.



    Is it possible to achieve? Is it a right way to do it?










    share|improve this question


























      up vote
      6
      down vote

      favorite
      1









      up vote
      6
      down vote

      favorite
      1






      1





      If i just use Option in for-comprehension everything goes as expected:



      val a = Some(1)
      val b = None
      val c = Some(3)

      val r = for {
      aa <- a
      bb <- b
      cc <- c
      } yield aa + bb + cc

      println(r) // None, because b is None


      but how to achieve the same behaviour using cats IO?



      import cats.effect.IO
      // in reality this will be a methods with side effect
      val a = Some(1)
      val b = None
      val c = Some(3)

      val r = for {
      _ <- IO{println("a"); a}
      _ <- IO{println("b"); b} // want to stop execution here
      _ <- IO{println("c"); c}
      } yield ()

      r.unsafeRunSync()


      In result i get a b c, but i expect only a b.



      Is it possible to achieve? Is it a right way to do it?










      share|improve this question















      If i just use Option in for-comprehension everything goes as expected:



      val a = Some(1)
      val b = None
      val c = Some(3)

      val r = for {
      aa <- a
      bb <- b
      cc <- c
      } yield aa + bb + cc

      println(r) // None, because b is None


      but how to achieve the same behaviour using cats IO?



      import cats.effect.IO
      // in reality this will be a methods with side effect
      val a = Some(1)
      val b = None
      val c = Some(3)

      val r = for {
      _ <- IO{println("a"); a}
      _ <- IO{println("b"); b} // want to stop execution here
      _ <- IO{println("c"); c}
      } yield ()

      r.unsafeRunSync()


      In result i get a b c, but i expect only a b.



      Is it possible to achieve? Is it a right way to do it?







      scala functional-programming monads scala-cats






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 20 at 13:51









      erip

      10.1k43674




      10.1k43674










      asked Nov 20 at 12:54









      Nick Ryan

      362213




      362213
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          7
          down vote



          accepted










          You can do this with monad transformers; specifically, you'll want to use OptionT[IO, T] here:



          import cats.effect._
          import cats.data.OptionT
          import cats.implicits._
          import cats.effect.IO

          val a = Some(1)
          val b = None
          val c = Some(3)

          val r = for {
          _ <- OptionT[IO, Int](IO {println("a"); a})
          _ <- OptionT[IO, Int](IO {println("b"); b})
          _ <- OptionT[IO, Int](IO {println("c"); c})
          } yield ()

          r.value.unsafeRunSync()


          See it in action here.






          share|improve this answer























          • Thank you! It's exactly what i need!
            – Nick Ryan
            Nov 20 at 13:37











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53393458%2fhow-to-stop-execution-in-for-comprehension-if-option-is-none-using-cats-io%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          7
          down vote



          accepted










          You can do this with monad transformers; specifically, you'll want to use OptionT[IO, T] here:



          import cats.effect._
          import cats.data.OptionT
          import cats.implicits._
          import cats.effect.IO

          val a = Some(1)
          val b = None
          val c = Some(3)

          val r = for {
          _ <- OptionT[IO, Int](IO {println("a"); a})
          _ <- OptionT[IO, Int](IO {println("b"); b})
          _ <- OptionT[IO, Int](IO {println("c"); c})
          } yield ()

          r.value.unsafeRunSync()


          See it in action here.






          share|improve this answer























          • Thank you! It's exactly what i need!
            – Nick Ryan
            Nov 20 at 13:37















          up vote
          7
          down vote



          accepted










          You can do this with monad transformers; specifically, you'll want to use OptionT[IO, T] here:



          import cats.effect._
          import cats.data.OptionT
          import cats.implicits._
          import cats.effect.IO

          val a = Some(1)
          val b = None
          val c = Some(3)

          val r = for {
          _ <- OptionT[IO, Int](IO {println("a"); a})
          _ <- OptionT[IO, Int](IO {println("b"); b})
          _ <- OptionT[IO, Int](IO {println("c"); c})
          } yield ()

          r.value.unsafeRunSync()


          See it in action here.






          share|improve this answer























          • Thank you! It's exactly what i need!
            – Nick Ryan
            Nov 20 at 13:37













          up vote
          7
          down vote



          accepted







          up vote
          7
          down vote



          accepted






          You can do this with monad transformers; specifically, you'll want to use OptionT[IO, T] here:



          import cats.effect._
          import cats.data.OptionT
          import cats.implicits._
          import cats.effect.IO

          val a = Some(1)
          val b = None
          val c = Some(3)

          val r = for {
          _ <- OptionT[IO, Int](IO {println("a"); a})
          _ <- OptionT[IO, Int](IO {println("b"); b})
          _ <- OptionT[IO, Int](IO {println("c"); c})
          } yield ()

          r.value.unsafeRunSync()


          See it in action here.






          share|improve this answer














          You can do this with monad transformers; specifically, you'll want to use OptionT[IO, T] here:



          import cats.effect._
          import cats.data.OptionT
          import cats.implicits._
          import cats.effect.IO

          val a = Some(1)
          val b = None
          val c = Some(3)

          val r = for {
          _ <- OptionT[IO, Int](IO {println("a"); a})
          _ <- OptionT[IO, Int](IO {println("b"); b})
          _ <- OptionT[IO, Int](IO {println("c"); c})
          } yield ()

          r.value.unsafeRunSync()


          See it in action here.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 20 at 13:38

























          answered Nov 20 at 13:33









          erip

          10.1k43674




          10.1k43674












          • Thank you! It's exactly what i need!
            – Nick Ryan
            Nov 20 at 13:37


















          • Thank you! It's exactly what i need!
            – Nick Ryan
            Nov 20 at 13:37
















          Thank you! It's exactly what i need!
          – Nick Ryan
          Nov 20 at 13:37




          Thank you! It's exactly what i need!
          – Nick Ryan
          Nov 20 at 13:37


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53393458%2fhow-to-stop-execution-in-for-comprehension-if-option-is-none-using-cats-io%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Wiesbaden

          Marschland

          Dieringhausen