for (x: String <- xs) yield... Why Hello There Tuple1

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

for (x: String <- xs) yield... Why Hello There Tuple1

Paul Phillips-3
With respect to this ticket:

  https://lampsvn.epfl.ch/trac/scala/ticket/900
  "Allow pattern matching on type in for comprehensions"

It is bandied about periodically with nontrivial resistance from martin
that this should work:

scala> val xs = List(1, "abc", 2, "def")
xs: List[Any] = List(1, abc, 2, def)

scala> for ((x: String) <- xs) yield x
<console>:7: error: type mismatch;
 found   : (String) => String
 required: (Any) => ?
      for ((x: String) <- xs) yield x
                        ^

It suddenly occurred to me that you can do it as below, and it does
work.  Which to me makes the case that it ought to work as given above
even stronger.

scala> for (Tuple1(x: String) <- xs map Tuple1.apply) yield x
res1: List[String] = List(abc, def)

scala> for (Tuple1(x: Int) <- xs map Tuple1.apply) yield x  
res2: List[Int] = List(1, 2)

And here you've all been thinking that Tuple1 isn't that useful.  I
think everyone owes Tuple1 a very nice apology.

--
Paul Phillips      | One way is to make it so simple that there are
Vivid              | obviously no deficiencies. And the other way is to make
Empiricist         | it so complicated that there are no obvious deficiencies.
slap pi uphill!    |     -- Hoare
Reply | Threaded
Open this post in threaded view
|

Re: for (x: String <- xs) yield... Why Hello There Tuple1

Martin Odersky


On Mon, Apr 26, 2010 at 11:07 PM, Paul Phillips <[hidden email]> wrote:
With respect to this ticket:

 https://lampsvn.epfl.ch/trac/scala/ticket/900
 "Allow pattern matching on type in for comprehensions"

It is bandied about periodically with nontrivial resistance from martin
that this should work:

scala> val xs = List(1, "abc", 2, "def")
xs: List[Any] = List(1, abc, 2, def)

scala> for ((x: String) <- xs) yield x
<console>:7: error: type mismatch;
 found   : (String) => String
 required: (Any) => ?
     for ((x: String) <- xs) yield x
                       ^

It suddenly occurred to me that you can do it as below, and it does
work.  Which to me makes the case that it ought to work as given above
even stronger.

scala> for (Tuple1(x: String) <- xs map Tuple1.apply) yield x
res1: List[String] = List(abc, def)

scala> for (Tuple1(x: Int) <- xs map Tuple1.apply) yield x
res2: List[Int] = List(1, 2)

And here you've all been thinking that Tuple1 isn't that useful.  I
think everyone owes Tuple1 a very nice apology.

Yay for Tuple1 ;-) Seriously, my concern is that people would take a declaration
x: T as a static type declaration and be very surprised if it turned into a dynamic filter.
We can argue where the line should be drawn. Is

for (x: T <- xs)   a static declaration? (currently, yes)

How about

for ((x: T) <- xs)   is this a static declaration? (currently, yes, but I am open to revise this one.)

Finally,

for (Tuple1(x: T) <- xs)   is a dynamic filter, and will continure to be one.

Cheers

 -- Martin

Reply | Threaded
Open this post in threaded view
|

Re: for (x: String <- xs) yield... Why Hello There Tuple1

Jason Zaugg
In reply to this post by Paul Phillips-3
My personal favourite:

scala> for (noreallyimapattern@(s: String) <- List(1, "two")) yield s
res9: List[String] = List(two)

:)

-jason

On Mon, Apr 26, 2010 at 11:07 PM, Paul Phillips <[hidden email]> wrote:
> scala> for (Tuple1(x: String) <- xs map Tuple1.apply) yield x
> res1: List[String] = List(abc, def)
>
> scala> for (Tuple1(x: Int) <- xs map Tuple1.apply) yield x
> res2: List[Int] = List(1, 2)
>
> And here you've all been thinking that Tuple1 isn't that useful.  I
> think everyone owes Tuple1 a very nice apology.
Reply | Threaded
Open this post in threaded view
|

Re: for (x: String <- xs) yield... Why Hello There Tuple1

Paul Phillips-3
In reply to this post by Martin Odersky
On Mon, Apr 26, 2010 at 11:14:10PM +0200, martin odersky wrote:
> We can argue where the line should be drawn. Is
>
> for (x: T <- xs)   a static declaration? (currently, yes)

Hey, I didn't even realize that parsed.  I think that just shifted my
opinion away from thinking that syntax ought to be a dynamic check.  I
don't know why someone would write an upcasting function like this, but
I agree that it has a static vibe.

scala> def f[T, U >: T](xs: List[T]) = for (x: U <- xs) yield x
f: [T,U >: T](xs: List[T])List[U]

--
Paul Phillips      | Giving every man a vote has no more made men wise
Imperfectionist    | and free than Christianity has made them good.
Empiricist         |     -- H. L. Mencken
ha! spill, pupil   |----------* http://www.improving.org/paulp/ *----------
Reply | Threaded
Open this post in threaded view
|

Re: for (x: String <- xs) yield... Why Hello There Tuple1

Xie Xiaodong
In reply to this post by Jason Zaugg
Hello, All,


I've got a question. 

Why the code by Paul need to changed into: 

for (Tuple1(x: String) <- xs map Tuple1.apply[Any]) yield x
for (Tuple1(x: Int) <- xs map Tuple1.apply[Any]) yield x

in order to get compiled under Scala version 2.7.7 final? 



On Mon, Apr 26, 2010 at 11:24 PM, Jason Zaugg <[hidden email]> wrote:
My personal favourite:

scala> for (noreallyimapattern@(s: String) <- List(1, "two")) yield s
res9: List[String] = List(two)

:)

-jason

On Mon, Apr 26, 2010 at 11:07 PM, Paul Phillips <[hidden email]> wrote:
> scala> for (Tuple1(x: String) <- xs map Tuple1.apply) yield x
> res1: List[String] = List(abc, def)
>
> scala> for (Tuple1(x: Int) <- xs map Tuple1.apply) yield x
> res2: List[Int] = List(1, 2)
>
> And here you've all been thinking that Tuple1 isn't that useful.  I
> think everyone owes Tuple1 a very nice apology.



--
Sincerely yours and Best Regards,
Xie Xiaodong
Reply | Threaded
Open this post in threaded view
|

Re: for (x: String <- xs) yield... Why Hello There Tuple1

Paul Phillips-3
In reply to this post by Jason Zaugg
On Mon, Apr 26, 2010 at 11:24:06PM +0200, Jason Zaugg wrote:
> scala> for (noreallyimapattern@(s: String) <- List(1, "two")) yield s
> res9: List[String] = List(two)

If that weren't the only construction in scala history where the
underscore doesn't have a role it might even be the real life winner.

scala> for (_ @ (s: String) <- List(1, "two")) yield s
<console>:6: error: type mismatch;
 found   : (String) => String
 required: (Any) => ?
       for (_ @ (s: String) <- List(1, "two")) yield s
                            ^

It works in straight matchland:

scala> def f(x: Any) = x match { case _ @ (x: String) => 1 ; case _ => 2 }
f: (x: Any)Int

Maybe we could make that work.

--
Paul Phillips      | One way is to make it so simple that there are
Analgesic          | obviously no deficiencies. And the other way is to make
Empiricist         | it so complicated that there are no obvious deficiencies.
slap pi uphill!    |     -- Hoare
Reply | Threaded
Open this post in threaded view
|

Re: for (x: String <- xs) yield... Why Hello There Tuple1

Jason Zaugg
Ditto for the case when the underscore and the identifier are switched.

scala> def f(x: Any) = x match { case x @ (_: String) => 1 ; case _ => 2 }
f: (x: Any)Int

scala> for (s@(_: String) <- List(1, "two")) yield s
<console>:6: error: type mismatch;
 found   : (String) => String
 required: (Any) => ?
       for (s@(_: String) <- List(1, "two")) yield s

On Mon, Apr 26, 2010 at 11:37 PM, Paul Phillips <[hidden email]> wrote:

> On Mon, Apr 26, 2010 at 11:24:06PM +0200, Jason Zaugg wrote:
>> scala> for (noreallyimapattern@(s: String) <- List(1, "two")) yield s
>> res9: List[String] = List(two)
>
> If that weren't the only construction in scala history where the
> underscore doesn't have a role it might even be the real life winner.
>
> scala> for (_ @ (s: String) <- List(1, "two")) yield s
> <console>:6: error: type mismatch;
>  found   : (String) => String
>  required: (Any) => ?
>       for (_ @ (s: String) <- List(1, "two")) yield s
>                            ^
> It works in straight matchland:
>
> scala> def f(x: Any) = x match { case _ @ (x: String) => 1 ; case _ => 2 }
> f: (x: Any)Int
>
> Maybe we could make that work.