Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala for-comprehension with tuple decomposition

for {
  a <- Some(1)
  b <- Some(2)
} yield (a, b)

returns Some((1, 2))

for {
  a <- Right(1).right
  b <- Left(2).left
} yield (a, b)

returns Left((1, 2))


Now I want to decompose tuples in the for comprehension.

for {
  (a, b) <- Some((1, 2))
  (c, d) <- Some((3, 4))
} yield (a, b, c, d)

returns Some((1, 2, 3, 4))

for {
  (a, b) <- Right((1, 2)).right
  (c, d) <- Left((3, 4)).left
} yield (a, b, c, d)

fails to compile:

error: constructor cannot be instantiated to expected type;
found   : (T1, T2)
required: scala.util.Either[Nothing,(Int, Int)]
                   (a, b) <- Right((1, 2)).right

error: constructor cannot be instantiated to expected type;
found   : (T1, T2)
required: scala.util.Either[(Int, Int),Nothing]

Why doesn't this last example work? What is the difference?

like image 942
Paul Draper Avatar asked Sep 18 '15 11:09

Paul Draper


People also ask

Is tuple immutable in Scala?

In Scala, a tuple is a value that contains a fixed number of elements, each with its own type. Tuples are immutable. Tuples are especially handy for returning multiple values from a method.

What is for comprehension in Scala?

Scala offers a lightweight notation for expressing sequence comprehensions. Comprehensions have the form for (enumerators) yield e , where enumerators refers to a semicolon-separated list of enumerators. An enumerator is either a generator which introduces new variables, or it is a filter.

Can we have variables of different types inside of a tuple Scala?

Thankfully, Scala already has a built-in tuple type, which is an immutable data structure that we can use for holding up to 22 elements with different types.


1 Answers

This is a bug:

SI-5589: For-comprehension on Either.RightProjection with Tuple2 extractor in generator fails to compile

withFilter() is called (some documentation references filter(), but that was changed in 2.8), which messes with the type inference.

withFilter() is used for things like for(a <- b if c), though according to the 6.19 it shouldn't be used in this case.

This latter bug is captured in SI-1336: spec requires type checking of for-comprehension to consider refutability, which has been open for seven years (2008).

Perhaps some future generation will find the fix.


See why does filter have to be defined for pattern matching in a for loop in scala?

like image 196
Paul Draper Avatar answered Sep 17 '22 20:09

Paul Draper