# Comprehension comprehension...

6 messages
Open this post in threaded view
|

## Comprehension comprehension...

 Hello and Happy Holidays!I was teaching some new developers the Joy Of ComprehensionI showed them that this yields a List   for { x <- List(1,2,3); y <- List(1,2,3) } yield x+y and this yields a Future  for { x <- Future(1); y <- Future(1) } yield x+y Then I asked them what type this would yield  for { x <- 1 to 3; y <- 1 to 3 } yield x+yand the answer was...  res3: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 3, 4, 3, 4, 5, 4, 5, 6)Huh?  That not what I thought should happen...  I expected a range, or a compile errorI thought perhaps Vector extended Range, but this does not compile  def foo(a: Range, b: Range): Range = for { x <- a; y <- b } yield x+yI thought the whole point of Monads and for comprehension is that the type does not change.Thoughts?P -- 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 [hidden email]. For more options, visit https://groups.google.com/d/optout.
Open this post in threaded view
|

## Re: Comprehension comprehension...

 Responding to Peter Wolf: > Then I asked them what type this would yield > >   for { x <- 1 to 3; y <- 1 to 3 } yield x+y > > and the answer was... > >   res3: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 3, 4, 3, 4, > 5, 4, 5, 6) > > Huh?  That not what I thought should happen...  I expected a range, or a > compile error How could it be a Range? What would start/end/step be for the result in your example? And what if you replace "x+y" with "(x+y).toString"? > I thought perhaps Vector extended Range, but this does not compile > >   def foo(a: Range, b: Range): Range = for { x <- a; y <- b } yield x+y > > I thought the whole point of Monads and for comprehension is that the type > does not change. Range itself cannot be "monadic", since its element type is fixed - it's not a type constructor of form M[A]. The "monadic" super type here basically is Traversable. But the Scala collection API works hard to give you a closer matching type, thus you end up with IndexedSeq, and the concrete instance happens to be a Vector. Best regards, Patrick -- 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 [hidden email]. For more options, visit https://groups.google.com/d/optout.
Open this post in threaded view
|

## Re: Comprehension comprehension...

 Cool.  With a little thought, I got that Range could not be a Monad.  I did not understand how the compiler finds a common matching type and does comprehension there.Here is another example`val x = for { x <- 1 to 2; y <- Set(1) } yield x+y````Vector(2, 3) ```On Fri, Dec 23, 2016 at 3:33 PM, Patrick Roemer wrote:Responding to Peter Wolf: > Then I asked them what type this would yield > >   for { x <- 1 to 3; y <- 1 to 3 } yield x+y > > and the answer was... > >   res3: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 3, 4, 3, 4, > 5, 4, 5, 6) > > Huh?  That not what I thought should happen...  I expected a range, or a > compile error How could it be a Range? What would start/end/step be for the result in your example? And what if you replace "x+y" with "(x+y).toString"? > I thought perhaps Vector extended Range, but this does not compile > >   def foo(a: Range, b: Range): Range = for { x <- a; y <- b } yield x+y > > I thought the whole point of Monads and for comprehension is that the type > does not change. Range itself cannot be "monadic", since its element type is fixed - it's not a type constructor of form M[A]. The "monadic" super type here basically is Traversable. But the Scala collection API works hard to give you a closer matching type, thus you end up with IndexedSeq, and the concrete instance happens to be a Vector. Best regards, Patrick -- You received this message because you are subscribed to a topic in the Google Groups "scala-user" group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/scala-user/WH49O9DGf44/unsubscribe. To unsubscribe from this group and all its topics, send an email to [hidden email]. For more options, visit https://groups.google.com/d/optout. -- 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 [hidden email]. For more options, visit https://groups.google.com/d/optout.
Open this post in threaded view
|

## Re: Comprehension comprehension...

 You can demonstrate this with less code, so e.g.scala> (1 to 3).map(_.toString)res0: scala.collection.immutable.IndexedSeq[String] = Vector(1, 2, 3)Recall that for comprehensions are just sugar for calls to map, flatMap, and withFilter. -- 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 [hidden email]. For more options, visit https://groups.google.com/d/optout.
 I recently said:https://gitter.im/scala/contributors?at=585cbe64c02c1a3959a25260to contrast``````scala> ('a' to 'e').slice(1,3) res1: scala.collection.immutable.IndexedSeq[Char] = Vector(b, c) scala> ('a' to 'e').drop(1).take(2) res2: scala.collection.immutable.NumericRange[Char] = NumericRange b to c``````and I said scaladoc promises a range here:``````scala> ('a' to 'e').patch(1, 'x' to 'z', 2) res6: scala.collection.immutable.IndexedSeq[Char] = Vector(a, x, y, z, d, e)``````So promises and expectations are broken. It would be nice if user could find out when or why.Also, our family nickname in the old country was Roemer, and my dog Roemer passed two years ago Christmas, so it's always a little jolt to see "Roemer". And the other dog was Padraig, Irish for Patrick. So I think I will go sing Auld Lang Syne now.On Friday, December 23, 2016 at 1:55:46 PM UTC-8, Patrick Roemer wrote:Responding to Peter Wolf: > With a little thought, I got that Range could not be a Monad.  I did not > understand how the compiler finds a common matching type and does > comprehension there. You can explore this in your IDE if you desugar. val x = (1 to 3).flatMap(x => (1 to 3).map(y => x + y)) IDEA shows that map/flatMap is resolved to TraversableLike, which returns an abstract That from the CanBuildFrom dance. The type hover on x shows it's an IndexedSeq[Int]. And "Explain Scala code" shows that the implicit argument to map/flatMap is IndexedSeq.canBuildFrom, indeed. > val x = for { x <- 1 to 2; y <- Set(1) } yield x+y > > Vector(2, 3) val y = for { y <- Set(1); x <- 1 to 2 } yield x+y Set(2, 3) :) Best regards, Patrick -- 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 [hidden email]. For more options, visit https://groups.google.com/d/optout.