foldLeft and /: strange behaviour

67 views
Skip to first unread message

Faisal Faizan

unread,
Apr 26, 2013, 11:17:09 PM4/26/13
to scala-l...@googlegroups.com
Hi,

I was going through "Chapter 16 of Programming in Scala, First Edition" and looking at the use of fold left operation (/:) to efficiently reverse a list. I got a surprising behavior difference between foldLeft and it's short form (/:). Though the scala API and the book says that both functions are one and the same they both give different results. I tried it in both scala worksheet and REPL.

Below is the code from my scala worksheet -

val xs  = List(1,2,3,4,5)                 //> xs  : List[Int] = List(1, 2, 3, 4, 5)
  def reverseLeft[T](xs: List[T]) =
    (List[T]() /: xs) {(ys, y) => y :: ys}        //> reverseLeft: [T](xs: List[T])List[T]
    
  def reverseLeft1[T](xs: List[T]) =
    (List[T]() foldLeft xs) {(ys, y) => y :: ys}  //> reverseLeft1: [T](xs: List[T])List[T]
  
  reverseLeft(xs)                                 //> res0: List[Int] = List(5, 4, 3, 2, 1)
  reverseLeft1(xs)                                //> res1: List[Int] = List(1, 2, 3, 4, 5)


So, using foldLeft is not giving me the correct behaviour here. reverseLeft1() is not reversing the list but reverseLeft() is.
Please suggest if I am missing something here.

Regards
Faisal




 

Chris Hodapp

unread,
Apr 26, 2013, 11:32:50 PM4/26/13
to scala-l...@googlegroups.com
/: is right-associative (since its name ends with ":"), while most functions are left-associative.
So, for reverseLeft, you are calling xs./:(List())(func).
For reverseLeft1, you are calling List().foldLeft(xs)(func).

The former does what you want (folds across the input list, using an empty list as an initial data value).
The latter folds across nothing, using your input list as the initial data value (so does nothing).

Also, you should use "Nil" rather than "List()", as it's more clear.

Faisal Faizan

unread,
Apr 27, 2013, 2:25:39 AM4/27/13
to scala-l...@googlegroups.com, scala-l...@googlegroups.com
Ahh... Thanks Chris, I am pretty new to Scala and though I have read about right associativity behaviour of methods ending with : but forgot to relate it here. Pretty interesting lesson learned. Thanks for your nice explanation and quick response.

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

Faisal Faizan

unread,
Apr 27, 2013, 5:57:07 AM4/27/13
to scala-l...@googlegroups.com, scala-l...@googlegroups.com
Also forgot to mention that  I can't use Nil as the type inferrer complains then

Sent from my iPhone

On 27-Apr-2013, at 9:02 AM, Chris Hodapp <clho...@gmail.com> wrote:

--

Vlad Patryshev

unread,
Apr 27, 2013, 1:18:40 PM4/27/13
to scala-l...@googlegroups.com
But you've produced a good and funny puzzler worth publishing/giving to students. :) Thank you!

Thanks,
-Vlad

Chris Hodapp

unread,
Apr 27, 2013, 2:35:28 PM4/27/13
to scala-l...@googlegroups.com
You are right. I am silly.

Type inferencing such that if you pass Nil into foldLeft as z (the initial value
of the passed-along data), it infers the type of the passed-along-data (B) to
be Nil.type. This means that values of type B can only be things statically
known to be Nil. Your solution to counteracting this is actually extremely
concise, so great job!

nafg

unread,
Apr 28, 2013, 1:31:12 AM4/28/13
to scala-l...@googlegroups.com
What I prefer to write, which is perhaps more clear in intent than List[T]() but still avoids Nil.type/List[Nothing], is List.empty[T].

Faisal Faizan

unread,
Apr 28, 2013, 2:35:19 AM4/28/13
to scala-l...@googlegroups.com, scala-l...@googlegroups.com
Thanks Vlad, good to hear that it can be published for other people's learning.

Sent from my iPhone

Chris Marshall

unread,
Apr 28, 2013, 3:04:56 PM4/28/13
to scala-l...@googlegroups.com, scala-l...@googlegroups.com
def nil[T]: List[T] = Nil
Reply all
Reply to author
Forward
0 new messages