This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Using the foldLeft operator /:

7 replies
Ståle Undheim
Joined: 2009-03-23,
User offline. Last seen 42 years 45 weeks ago.

I am trying to figure out how to use the /: operator in scala.
According to the doc it's similar to foldLeft
from http://www.scala-lang.org/docu/files/api/scala/Iterable.html#%2F%3A%28B%29:

Similar to foldLeft but can be used as an operator with the order of
list and zero arguments reversed. That is, z /: xs is the same as xs
foldLeft z

So, say I want to sum a range of numbers:
(1 to 100).foldLeft(0)(_+_)

This works, as does:
(1 to 100)./:(0)(_+_)

But how do I write the same expression using /: without the "."?

I have tried:
scala> (1 to 100) /:(0)(_+_)
:5: error: 0 of type Int(0) does not take parameters

as well as:
(_+_) /: (1 to 100)
:5: error: missing parameter type for expanded function
((x$1, x$2) => x$1.$plus(x$2))
(_+_) /: (1 to 100)

How should I sum a set off numbers using the /: operator? How would I
do it if I need to change to BigInt on the fly (because off int
overflow)?
The last one is easy with foldLeft:
(1 to 100).foldLeft(BigInt(0))(_+_)

Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: Using the foldLeft operator /:
(0 /: (1 to 100))(_ + _)

/: ends with a colon, thus it is right-associative, i.e., it is a member of the object on its right, not its left.

2009/4/21 Ståle Undheim <staaleu [at] gmail [dot] com>
I am trying to figure out how to use the /: operator in scala.
According to the doc it's similar to foldLeft
from http://www.scala-lang.org/docu/files/api/scala/Iterable.html#%2F%3A%28B%29:

Similar to foldLeft but can be used as an operator with the order of
list and zero arguments reversed. That is, z /: xs is the same as xs
foldLeft z

So, say I want to sum a range of numbers:
(1 to 100).foldLeft(0)(_+_)

This works, as does:
(1 to 100)./:(0)(_+_)

But how do I write the same expression using /: without the "."?

I have tried:
scala> (1 to 100) /:(0)(_+_)
<console>:5: error: 0 of type Int(0) does not take parameters

as well as:
(_+_) /: (1 to 100)
<console>:5: error: missing parameter type for expanded function
((x$1, x$2) => x$1.$plus(x$2))
      (_+_) /: (1 to 100)

How should I sum a set off numbers using the /: operator? How would I
do it if I need to change to BigInt on the fly (because off int
overflow)?
The last one is easy with foldLeft:
(1 to 100).foldLeft(BigInt(0))(_+_)

Szabolcs Berecz
Joined: 2009-04-11,
User offline. Last seen 42 years 45 weeks ago.
Re: Using the foldLeft operator /:

scala> (0 /: (1 to 100)) (_ + _)
res1: Int = 5050

On Tue, Apr 21, 2009 at 14:30, Ståle Undheim wrote:
> I am trying to figure out how to use the /: operator in scala.
> According to the doc it's similar to foldLeft
> from http://www.scala-lang.org/docu/files/api/scala/Iterable.html#%2F%3A%28B%29:
>
> Similar to foldLeft but can be used as an operator with the order of
> list and zero arguments reversed. That is, z /: xs is the same as xs
> foldLeft z
>
> So, say I want to sum a range of numbers:
> (1 to 100).foldLeft(0)(_+_)
>
> This works, as does:
> (1 to 100)./:(0)(_+_)
>
> But how do I write the same expression using /: without the "."?
>
> I have tried:
> scala> (1 to 100) /:(0)(_+_)
> :5: error: 0 of type Int(0) does not take parameters
>
> as well as:
> (_+_) /: (1 to 100)
> :5: error: missing parameter type for expanded function
> ((x$1, x$2) => x$1.$plus(x$2))
>       (_+_) /: (1 to 100)
>
> How should I sum a set off numbers using the /: operator? How would I
> do it if I need to change to BigInt on the fly (because off int
> overflow)?
> The last one is easy with foldLeft:
> (1 to 100).foldLeft(BigInt(0))(_+_)
>

Seth Tisue
Joined: 2008-12-16,
User offline. Last seen 34 weeks 3 days ago.
Pattern matching on Stream using #::

On trunk I can use #:: as an infix way of writing Stream.cons:

scala> 1 #:: Stream.empty
res2: scala.collection.immutable.Stream[Int] = Stream(1, ?)

I like it. There's also an extractor so you can pattern match
the same way:

scala> Stream(1,2,3) match { case x #:: xs => (x,xs) }
res3: (Int, scala.collection.immutable.Stream[Int]) = (1,Stream(2, ?))

I like this too, but it doesn't work unless you do this first:

import Stream.#::

it seems like this may have been an oversight? shall I open a ticket?
I don't need to import :: in order to pattern match lists (thanks
to some magic in Predef.scala)

Walter Chang
Joined: 2008-08-21,
User offline. Last seen 3 years 26 weeks ago.
Re: Pattern matching on Stream using #::
+1 on putting it in Predef

On Thu, Jul 23, 2009 at 12:37 AM, Seth Tisue <seth [at] tisue [dot] net> wrote:

On trunk I can use #:: as an infix way of writing Stream.cons:

scala> 1 #:: Stream.empty
res2: scala.collection.immutable.Stream[Int] = Stream(1, ?)

I like it.  There's also an extractor so you can pattern match
the same way:

scala> Stream(1,2,3) match { case x #:: xs => (x,xs) }
res3: (Int, scala.collection.immutable.Stream[Int]) = (1,Stream(2, ?))

I like this too, but it doesn't work unless you do this first:

import Stream.#::

it seems like this may have been an oversight?  shall I open a ticket?
I don't need to import :: in order to pattern match lists (thanks
to some magic in Predef.scala)

--
Seth Tisue / http://tisue.net
lead developer, NetLogo: http://ccl.northwestern.edu/netlogo/



--
.......__o
.......\<,
....( )/ ( )...
John Nilsson
Joined: 2008-12-20,
User offline. Last seen 42 years 45 weeks ago.
Fwd: Pattern matching on Stream using #::

Forgot, reply to all...

---------- Forwarded message ----------
From: John Nilsson
Date: Wed, Jul 22, 2009 at 6:54 PM
Subject: Re: [scala] Pattern matching on Stream using #::
To: Walter Chang

Why #:: and not just ::

Is it because they are objects, and you can't overload objects? If so,
should anything be done to fix this situation?

BR,
John

On Wed, Jul 22, 2009 at 6:45 PM, Walter Chang wrote:
> +1 on putting it in Predef
>
> On Thu, Jul 23, 2009 at 12:37 AM, Seth Tisue wrote:
>>
>> On trunk I can use #:: as an infix way of writing Stream.cons:
>>
>> scala> 1 #:: Stream.empty
>> res2: scala.collection.immutable.Stream[Int] = Stream(1, ?)
>>
>> I like it.  There's also an extractor so you can pattern match
>> the same way:
>>
>> scala> Stream(1,2,3) match { case x #:: xs => (x,xs) }
>> res3: (Int, scala.collection.immutable.Stream[Int]) = (1,Stream(2, ?))
>>
>> I like this too, but it doesn't work unless you do this first:
>>
>> import Stream.#::
>>
>> it seems like this may have been an oversight?  shall I open a ticket?
>> I don't need to import :: in order to pattern match lists (thanks
>> to some magic in Predef.scala)
>>
>> --
>> Seth Tisue / http://tisue.net
>> lead developer, NetLogo: http://ccl.northwestern.edu/netlogo/
>
>
>
> --
> .......__o
> .......\<,
> ....( )/ ( )...
>

Jiří Paleček
Joined: 2009-07-20,
User offline. Last seen 42 years 45 weeks ago.
Re: Fwd: Pattern matching on Stream using #::

Dne Wed, 22 Jul 2009 16:55:14 -0000 John Nilsson
napsal(a):

> Forgot, reply to all...
>
>
> ---------- Forwarded message ----------
> From: John Nilsson
> Date: Wed, Jul 22, 2009 at 6:54 PM
> Subject: Re: [scala] Pattern matching on Stream using #::
> To: Walter Chang
>
>
> Why #:: and not just ::
>
> Is it because they are objects, and you can't overload objects? If so,
> should anything be done to fix this situation?

Actually, you don't need :: to be "overloaded object". :: just needs to be
a value with unapply method handling both alternatives (both Streams and
Lists). There's a little obstacle that the tail method is not an abstract
method of a common base of these two, but that can be solved easily in
Scala. See:

scala> val fff = new { def unapply[A, T](x : { def head : A; def tail : T;
def isEmpty : Boolean }) = if(x.isEmpty) None else Some(x.head, x.tail) }
fff: java.lang.Object{def unapply[A,T](AnyRef{def head: A; def tail: T;
def isEmpty: Boolean}): Option[(A, T)]} = $anon$1@32b90a0

scala> fff.unapply(List(1,2))
res112: Option[(Int, List[Int])] = Some((1,List(2)))

scala> List(1,2,3) match { case x fff xs => (x, xs
| )}
res113: (Int, List[Int]) = (1,List(2, 3))

scala> Stream(1,2,3) match { case x fff xs => (x, xs)}
res114: (Int, Stream[Int]) = (1,Stream(2, ?))

Regards
Jiri Palecek

PS: please, Cc: me in replies.

> BR,
> John
>
> On Wed, Jul 22, 2009 at 6:45 PM, Walter Chang wrote:
>> +1 on putting it in Predef
>>
>> On Thu, Jul 23, 2009 at 12:37 AM, Seth Tisue wrote:
>>>
>>> On trunk I can use #:: as an infix way of writing Stream.cons:
>>>
>>> scala> 1 #:: Stream.empty
>>> res2: scala.collection.immutable.Stream[Int] = Stream(1, ?)
>>>
>>> I like it. There's also an extractor so you can pattern match
>>> the same way:
>>>
>>> scala> Stream(1,2,3) match { case x #:: xs => (x,xs) }
>>> res3: (Int, scala.collection.immutable.Stream[Int]) = (1,Stream(2, ?))
>>>
>>> I like this too, but it doesn't work unless you do this first:
>>>
>>> import Stream.#::
>>>
>>> it seems like this may have been an oversight? shall I open a ticket?
>>> I don't need to import :: in order to pattern match lists (thanks
>>> to some magic in Predef.scala)
>>>
>>> --
>>> Seth Tisue / http://tisue.net
>>> lead developer, NetLogo: http://ccl.northwestern.edu/netlogo/
>>
>>
>>
>> --
>> .......__o
>> .......\<,
>> ....( )/ ( )...
>>
>

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: Pattern matching on Stream using #::

The wrapper for :: is actually in the scala package object, not in
Predef. I have put another one fdor #:: in he same place now, so
extractors should work with tomorrows nightly. Thanks for the
suggestion.

Cheers

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland