Pattern match on value of Either inside a for comprehension?

I have a for comprehension like this:

for {
      (value1: String, value2: String, value3: String) <- getConfigs(args)
      // more stuff using those values
}

getConfigs returns an Either[Throwable, (Seq[String], String, String)] and when I try to compile I get this error:

value withFilter is not a member of Either[Throwable,(Seq[String], String, String)]

How can I use this method (that returns an Either) in the for comprehension?


Pattern match on value of Either inside a for comprehension?, The problem (see above) is not that for comprehensions are not possible but that pattern matching inside the for comprehension is not possible within Either. The problem (see above) is not that for comprehensions are not possible but that pattern matching inside the for comprehension is not possible within Either. There is documentation how for comprehensions are translated but they don't cover each case. This one is not covered there, as far as I can see.


I guess you want your loop to run only if the value is a Right. If it is a Left, it should not run. This can be achieved really easy:

for {
  (value1, value2, value3) <- getConfigs(args).right.toOption
  // more stuff using those values
}

Sidenote: I don't know whats your exact use case, but scala.util.Try is better suited for cases where you either have a result or a failure (an exception). Just write Try { /*some code that may throw an exception*/ } and you'll either have Success(/*the result*/) or a Failure(/*the caught exception*/). If your getConfigs method returns a Try instead of Either, then your above could would work without any changes.

Scala: comprehending the for-comprehension, It will either contain some generic value, or contain no value. Now, we will try to print a value contained in one of the objects we just created, stay tuned — I will follow with a similar post about Scala pattern matching soon. Sometimes, when matching a sub-pattern within a value, it may be useful to bind a name to the whole value being matched. As-patterns allow exactly this: they are of the form var@pattern and have the additional effect to bind the name var to the whole value being matched by pattern .


I think the part you may find surprising is that the Scala compiler emits this error because you deconstruct the tuple in place. This is surprisingly forces the compiler to check for withFilter method because it looks to the compilers like an implicit check for the type of the value inside the container and checks on values are implemented using withFilter. If you write your code as

  for {
    tmp <- getConfigs(args)
    (value1: Seq[String], value2: String, value3: String) = tmp
    // more stuff using those values
  } 

it should compile without errors.

Pattern match typing fail in for comprehension · Issue #7222 · scala , Either[Nothing,(String, String)] (a, b) <- foo.right ^ fred.scala:6: error: not found: value a a + b ^ two errors found On Tue, Mar 5, 2013 at 6:20 PM,  Pattern matching is a mechanism for checking a value against a pattern. A successful match can also deconstruct a value into its constituent parts. It is a more powerful version of the switch statement in Java and it can likewise be used in place of a series of if/else statements.


You can do this using Oleg's better-monadic-for compiler plugin:

build.sbt:

addCompilerPlugin("com.olegpy" %% "better-monadic-for" % "0.2.4")

And then:

object Test {
  def getConfigs: Either[Throwable, (String, String, String)] = Right(("a", "b", "c"))

  def main(args: Array[String]): Unit = {
    val res = for {
      (fst, snd, third) <- getConfigs
    } yield fst

    res.foreach(println)
  }
}

Yields:

a

This works because the plugin removes the unnecessary withFilter and unchecked while desugaring and uses a .map call. Thus, we get:

val res: Either[Throwable, String] = 
  getConfigs
    .map[String](((x$1: (String, String, String)) => x$1 match {
      case (_1: String, _2: String, _3: String)
    (String, String, String)((fst @ _), (snd @ _), (third @ _)) => fst
})); 

Matching in for-comprehensions, As shown in post: for-comprehensions, for-comprehensions can have But what is interesting is that the pattern matching can act as a guard as well. +); scala> for {Property(key,value) <- args } yield (Symbol(key),value); res0: object NotNull{def unapply[A <: AnyRef](ref: A): Option[A] = if (ref eq null)  ? : match zero or one occurrence of the pattern to the left (i.e., may or may not appear in pattern) - : if between two [], indicates a range of digits or alphabetic chars; will be interpreted as a literal if appearing first or last inside []. * : zero or more occurrences of a pattern to the left of


3 Useful Things About Scala's Either Class That You Want To Know, In this article, I want to share some useful Either characteristic that I think is This makes it very hard to compose sequence using for comprehension. you want to do a left and right value without doing a pattern-matching. The default setting of 1 can cause MATCH to return results that look "normal" but are in fact incorrect. I recommend always providing a value for match_type, as a reminder of what behavior is expected. Basic exact match. When match type is set to zero, MATCH performs an exact match. In the example below, the formula in E3 is: =


For Comprehensions | Tour of Scala, An enumerator is either a generator which introduces new variables, or it is a filter. binding generated by the enumerators and returns a sequence of these values. Here's an example: case class User(name: String, age: Int) val userBase = List( User("Travis", 28), Other examples of “For comprehension” in the Scala Book. An enumerator is either a generator which introduces new variables, or it is a filter. A comprehension evaluates the body e for each binding generated by the enumerators and returns a sequence of these values.


How to process multiple Option values in a Scala 'for' loop , How to process multiple Option values in a Scala 'for' loop want to see a for comprehension that processes multiple input Option values, here you go: true case None => // it matched our pattern, but we couldn't extract the  Pattern Matching. 04/10/2019; 13 minutes to read +5; In this article. Patterns test that a value has a certain shape, and can extract information from the value when it has the matching shape. Pattern matching provides more concise syntax for algorithms you already use today. You already create pattern matching algorithms using existing syntax.