<console>:12: error: type mismatch; found : scala.util.Try[Int] required: scala.collection.GenTraversableOnce[?]

784 views
Skip to first unread message

Rahat Hossain

unread,
Dec 29, 2013, 2:26:13 AM12/29/13
to scala...@googlegroups.com
Hi All,

I am bit confused regarding following error. 
What I am doing wrong ? 

scala> for { x <- List(Try(1), Try(3)); y <- x } yield y
<console>:12: error: type mismatch;
 found   : scala.util.Try[Int]
 required: scala.collection.GenTraversableOnce[?]
              for { x <- List(Try(1), Try(3)); y <- x } yield y
                                                 ^

Marius Danciu

unread,
Dec 29, 2013, 3:00:54 AM12/29/13
to Rahat Hossain, scala-user
You use two different types of monads in your for comprehension: List and Try. Decomposing it would be:

List(Try(1), Try(3)).flatMap{x => x.map{y => y}}

So flatMap needs to return another List  whereas it returns a Try... so types obviously don't match.

Marius


--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Shrivats

unread,
Dec 29, 2013, 3:01:27 AM12/29/13
to Rahat Hossain, scala-user
I guess you've misunderstood what `x` contains here - Just an item out of the `List(Try(1), Try(3))`. 

Can you understand what's going on here below?

scala> import scala.util.Try
import scala.util.Try

scala> val x = List(Try(1), Try(3))
x: List[scala.util.Try[Int]] = List(Success(1), Success(3))

scala> for (y <- x) yield y
res0: List[scala.util.Try[Int]] = List(Success(1), Success(3))

In your code sample, since `x` contained only one item, scala complained that it cannot iterate over a single value. 
IOW, `x` is not something to iterate over. 

Have a look at scala docs[1] to further your understanding. 

HTH, 

Shrivats



Rahat Hossain

unread,
Dec 29, 2013, 4:25:17 AM12/29/13
to scala...@googlegroups.com, Rahat Hossain
Hi Marius,

Thanks a lot. It make sense. 

scala> for { x <- List(List(1), List(3)); y <- x } yield y
res224: List[Int] = List(1, 3)

scala> for { x <- Set(List(1), Set(3)); y <- x } yield y
res228: scala.collection.immutable.Set[Int] = Set(1, 3)


Now I got another confusion, which is as follows:  

scala> for { x <- Try(Try(1), Try(3)); y <- x } yield y
<console>:15: error: value map is not a member of (scala.util.Try[Int], scala.util.Try[Int])
              for { x <- Try(Try(1), Try(3)); y <- x } yield y
                                                   ^

Marius Danciu

unread,
Dec 29, 2013, 6:05:29 AM12/29/13
to Rahat Hossain, scala-user
That is because of auto-tupling I think:

scala> val x = Try(Try(1), Try(3))
x: scala.util.Try[(scala.util.Try[Int], scala.util.Try[Int])] = Success((Success(1),Success(3)))

and a tuple has no map/flatMap thinkgs.


Marius

Rahat Hossain

unread,
Dec 29, 2013, 3:32:40 PM12/29/13
to scala...@googlegroups.com, Rahat Hossain
Hi Marius,

Thanks a lot, this really makes sense now.
But now question is, is this auto-tupling a bug? 
if I use List, that time this auto-tupling is not happening, but when using Try that time happening. 

Som Snytt

unread,
Dec 29, 2013, 5:01:52 PM12/29/13
to Rahat Hossain, scala-user
> is this auto-tupling a bug?

That depends on whom you ask.

For completeness,

scala> for (x <- List(Try(1),Try(3)) map (_.toOption); y <- x) yield y
res0: List[Int] = List(1, 3)

Rahat Hossain

unread,
Dec 29, 2013, 6:50:23 PM12/29/13
to scala...@googlegroups.com, Rahat Hossain
Hi Som,

Thanks a lot. That's what I was really upto.  

scala> val ran = new Random
ran: scala.util.Random = scala.util.Random@1e184a1

scala> def isTrue = ran.nextBoolean
isTrue: Boolean

scala> def flakyInt = if(isTrue) ran.nextInt else throw new Exception
flakyInt: Int

scala> for( x <- List( Try(flakyInt), Try(flakyInt), Try(flakyInt) ) map (_.toOption);  y <- x ) yield y
res63: List[Int] = List(-60142352, 1028243548)

Naftoli Gugenheim

unread,
Jan 1, 2014, 9:03:25 PM1/1/14
to Rahat Hossain, scala-user

That's because List *expects* multiple arguments. Auto-tupling means that when you call f(a, b...) where f takes only one argument, the compiler inserts an extra set of parentheses for you, so you end up passing f one tuple-valued argument, rather than getting a compiler error for wrong number of arguments.

Reply all
Reply to author
Forward
0 new messages