How to implement a short-circuit with IO monad in Scala

Yann Moisan

I use a standard IO monad.

And at some point, i need to shortcircuit. On a given condition, i don't want to run the following ios.

Here is my solution, but I found it too verbose and not elegant :

  def shortCircuit[A](io: IO[A], continue: Boolean) =
    io.map(a => if (continue) Some(a) else None)

  for {
    a <- io
    b <- shortCircuit(io, a == 1)
    c <- shortCircuit(io, b.map(_ == 1).getOrElse(false))
    d <- shortCircuit(io, b.map(_ == 1).getOrElse(false))
    e <- shortCircuit(io, b.map(_ == 1).getOrElse(false))
  } yield …

For example, for 3rd, 4th and 5th line, I need to repeat the same condition.

Is there a better way ?

Rex Kerr

You haven't actually short-circuited anything there. You are still running the IOs; you just don't capture the values.

Also, the standard IO monad doesn't define filter (or withFilter), so you can't use guards in your for-comprehension.

Now, if you want just what you've said (same logic, just more DRY), you can always assign a temporary variable in the for comprehension:

for {
  a <- io
  b <- shortCircuit(io, a == 1)
  continue = b.map(_ == 1).getOrElse(false)
  c <- shortCircuit(io, continue)
  d <- shortCircuit(io, continue)
  e <- shortCircuit(io, continue)
} yield …

But if you actually want to short-circuit, you will have to break apart the cases in some way. Here's one possibility, assuming you just want to pack everything into an array so the return type is simple, and your IO companion object has an apply method that you can use to create something that just returns a value:

io.flatMap(a =>
  if (a == 1) IO(() => Array(a))
  else io.flatMap(b =>
    if (b == 1) IO(() => Array(a,b))
    else for {
      c <- io
      d <- io
      e <- io
    } yield Array(a,b,c,d,e)
  )
)

If your return types are more complicated, you may have to work harder with specifying types.

FWIW, it is worth noting the penalty that you pay for keeping things wrapped in monads; without, the same logic would be (for example):

io() match {
  case 1 => Array(1)
  case a => io() match {
    case 1 => Array(a, 1)
    case b => Array(a, b, io(), io(), io())
  }
}

And if you allow returns, you get:

val a = io()
if (a == 1) return Array(a)
val b = io()
if (b == 1) return Array(a, b)
Array(a, b, io(), io(), io())

It's also possible in principle to decorate the IO monad with extra methods that help out a bit, but the standard withFilter won't work so you won't be able to use the for-comprehension syntactic sugar.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Short-circuit AND within IO Monad

From Dev

How to implement the `List` monad transformer in Scala?

From Dev

How to implement the `List` monad transformer in Scala?

From Dev

How to short-circuit a @CustomValidator?

From Dev

Lodash how to short circuit terminate

From Dev

How to simulate short circuit and in opencv

From Dev

IO monad prevents short circuiting of embedded mapM?

From Dev

How to short-circuit reduce on Stream?

From Dev

How to Short-Circuit SQL Where Clause

From Dev

How to short-circuit a reduce() operation on a Stream?

From Dev

Scala IO monad: what's the point?

From Dev

Scala IO monad: what's the point?

From Dev

Idiomatic Scala.js translation of JavaScript short circuit evaluation

From Java

Scala, cats - how to create tagless-final implementation with IO (or other monad) and Either?

From Dev

How to implement a reader monad to access a database

From Dev

How to invoke short-circuit logical operators in MATLAB as a function?

From Dev

How to perform short-circuit evaluation in Windows PowerShell 4.0?

From Dev

In Meteor, how to short-circuit-assign a helper variable with user object?

From Dev

How to retrieve the return code of a command in a short-circuit expression

From Dev

In Meteor, how to short-circuit-assign a helper variable with user object?

From Dev

How to achieve the equivalent of "short-circuit evaluation" in T-sql

From Dev

HDFS Short circuit reads

From Dev

Short circuit template instantiation

From Dev

Short Circuit Evaluation to undefined?

From Dev

short circuit with a return statement

From Dev

is sqlite short circuit in WHERE

From Dev

JavaScript Short Circuit Logic

From Dev

Conditional && fails to short circuit

From Dev

Ternary to Short-Circuit

Related Related

  1. 1

    Short-circuit AND within IO Monad

  2. 2

    How to implement the `List` monad transformer in Scala?

  3. 3

    How to implement the `List` monad transformer in Scala?

  4. 4

    How to short-circuit a @CustomValidator?

  5. 5

    Lodash how to short circuit terminate

  6. 6

    How to simulate short circuit and in opencv

  7. 7

    IO monad prevents short circuiting of embedded mapM?

  8. 8

    How to short-circuit reduce on Stream?

  9. 9

    How to Short-Circuit SQL Where Clause

  10. 10

    How to short-circuit a reduce() operation on a Stream?

  11. 11

    Scala IO monad: what's the point?

  12. 12

    Scala IO monad: what's the point?

  13. 13

    Idiomatic Scala.js translation of JavaScript short circuit evaluation

  14. 14

    Scala, cats - how to create tagless-final implementation with IO (or other monad) and Either?

  15. 15

    How to implement a reader monad to access a database

  16. 16

    How to invoke short-circuit logical operators in MATLAB as a function?

  17. 17

    How to perform short-circuit evaluation in Windows PowerShell 4.0?

  18. 18

    In Meteor, how to short-circuit-assign a helper variable with user object?

  19. 19

    How to retrieve the return code of a command in a short-circuit expression

  20. 20

    In Meteor, how to short-circuit-assign a helper variable with user object?

  21. 21

    How to achieve the equivalent of "short-circuit evaluation" in T-sql

  22. 22

    HDFS Short circuit reads

  23. 23

    Short circuit template instantiation

  24. 24

    Short Circuit Evaluation to undefined?

  25. 25

    short circuit with a return statement

  26. 26

    is sqlite short circuit in WHERE

  27. 27

    JavaScript Short Circuit Logic

  28. 28

    Conditional && fails to short circuit

  29. 29

    Ternary to Short-Circuit

HotTag

Archive