What's the new name for map2 in Scalaz 7? - scala

Jordan West in this presentation from Scalamachine clearly speaks about map2 function. Turns out the function was available in Scalaz 6 but I can't find it or any equivalent in Scalaz 7.
E.g. I would like to be able to run this code:
List(Some(1), Some(2)).map2(_ + 1)
and get as a result
List(Some(2), Some(3))
Where can I find this function in Scalaz 7?
EDIT:
Ideally, I would like to be able to execute any function f: A => B on l: List[Option[A]]
l.map2(f)
And get List[Option[B]] with the intuitive semantics.

You can use the applicative syntax instead:
scala> List(Some(1), Some(2)) <*> List((x:Option[Int]) => x |+| Some(1))
res0: List[Option[Int]] = List(Some(2), Some(3))
Scalaz 7 is a different beast compared to Scalaz 6.

I haven't found map2 in scalaz 7 and the applicative approach by #I.K. is the most similar I could think. However in this situation where the "shape of the list" doesn't change, I would map and mappend:
List(1.some, 2.some) map (_ |+| 1.some)
res: List[Option[Int]] = List(Some(2), Some(3))
Of course if the default operation assigned to the type is not the desired one, then I would use an exiting Tag from scalaz or a custom implicit.
EDIT
I have just noticed your answer: the other-way-round expected result could be achieved using traverse
List(1.some, 2.some, 3.some) traverseU (_ |+| 1.some)
Some(List(2, 3, 4))

Ok, there does not seem to exist such function in Scalaz 7 but there is a nice way around using Monad Transformers:
OptionT[List, Int](List(Some(1), Some(2))).map(_ + 1).run
// List(Some(2), Some(3))
or in the case of l: List[Option[A]]
OptionT[List, A](l).map(f).run

Related

Why the variation in operators?

Long time lurker, first time poster.
In Scala, I'm looking for advantages as to why it was preferred to vary operators depending on type. For example, why was this:
Vector(1, 2, 3) :+ 4
determined to be an advantage over:
Vector(1, 2, 3) + 4
Or:
4 +: Vector(1,2,3)
over:
Vector(4) + Vector(1,2,3)
Or:
Vector(1,2,3) ++ Vector(4,5,6)
over:
Vector(1,2,3) + Vector(4,5,6)
So, here we have :+, +:, and ++ when + alone could have sufficed. I'm new at Scala, and I'll succumb. But, this seems unnecessary and obfuscated for a language that tries to be clean with its syntax.
I've done quite a few google and stack overflow searches and have only found questions about specific operators, and operator overloading in general. But, no background on why it was necessary to split +, for example, into multiple variations.
FWIW, I could overload the operators using implicit classes, such as below, but I imagine that would only cause confusion (and tisk tisks) from experienced Scala programmers using/reading my code.
object AddVectorDemo {
implicit class AddVector(vector : Vector[Any]) {
def +(that : Vector[Any]) = vector ++ that
def +(that : Any) = vector :+ that
}
def main(args : Array[String]) : Unit = {
val u = Vector(1,2,3)
val v = Vector(4,5,6)
println(u + v)
println(u + v + 7)
}
}
Outputs:
Vector(1, 2, 3, 4, 5, 6)
Vector(1, 2, 3, 4, 5, 6, 7)
The answer requires a surprisingly long detour through variance. I'll try to make it as short as possible.
First, note that you can add anything to an existing Vector:
scala> Vector(1)
res0: scala.collection.immutable.Vector[Int] = Vector(1)
scala> res0 :+ "fish"
res1: scala.collection.immutable.Vector[Any] = Vector(1, fish)
Why can you do this? Well, if B extends A and we want to be able to use Vector[B] where Vector[A] is called for, we need to allow Vector[B] to add the same sorts of things that Vector[A] can add. But everything extends Any, so we need to allow addition of anything that Vector[Any] can add, which is everything.
Making Vector and most other non-Set collections covariant is a design decision, but it's what most people expect.
Now, let's try adding a vector to a vector.
scala> res0 :+ Vector("fish")
res2: scala.collection.immutable.Vector[Any] = Vector(1, Vector(fish))
scala> res0 ++ Vector("fish")
res3: scala.collection.immutable.Vector[Any] = Vector(1, fish)
If we only had one operation, +, we wouldn't be able to specify which one of these things we meant. And we really might mean to do either. They're both perfectly sensible things to try. We could try to guess based on types, but in practice it's better to just ask the programmer to explicitly say what they mean. And since there are two different things to mean, there need to be two ways to ask.
Does this come up in practice? With collections of collections, yes, all the time. For example, using your +:
scala> Vector(Vector(1), Vector(2))
res4: Vector[Vector[Int]] = Vector(Vector(1), Vector(2))
scala> res4 + Vector(3)
res5: Vector[Any] = Vector(Vector(1), Vector(2), 3)
That's probably not what I wanted.
It's a fair question, and I think it has a lot to do with legacy code and Java compatibility. Scala copied Java's + for String concatenation, which has complicated things.
This + allows us to do:
(new Object) + "foobar" //"java.lang.Object#5bb90b89foobar"
So what should we expect if we had + for List and we did List(1) + "foobar"? One might expect List(1, "foobar") (of type List[Any]), just like we get if we use :+, but the Java-inspired String-concatenation overload would complicate this, since the compiler would fail to resolve the overload.
Odersky even once commented:
One should never have a + method on collections that are covariant in their element type. Sets and maps are non-variant, that's why they can have a + method. It's all rather delicate and messy. We'd be better off if we did not try to duplicate Java's + for String concatenation. But when Scala got designed the idea was to keep essentially all of Java's expression syntax, including String +. And it's too late to change that now.
There is some discussion (although in a different context) on the answers to this similar question.

Summing up two options

Let's say I have two optional Ints (both can be Some or None):
val one : Option[Int] = Some(1)
val two : Option[Int] = Some(2)
My question is the following: Are there any intelligent way to sum them op using Scalas brilliant collection-methods? I realize that I could merge them into a collection, flatten it and use reduceLeftOption like so:
(one :: two :: Nil).flatten.reduceLeftOption(_ + _) // Some(3)
But, the solution above means creating a new collection, and living in a rich and developed world that takes time from all the other first world activities I might immerse myself into. And in a world where programming gets more and more luxurious for programmers like us, there must be one or more luxurious first world answer(s) to this, right?
Edit: So to spell things out, here are some examples:
If one = Some(1) and two = Some(2) we should have Some(3)
If one = Some(1) and two = None we should have Some(1)
If one = None and two = Some(2) we should have Some(2)
If both one and two are None we should have None, since neither one or two can be summed correctly.
Hope that clarified things :-)
for (x <-one; y <- two) yield x+y
Or the less readable but strictly equivalent:
one.flatMap{x=>two.map(x+_)}
UPDATE: As your latest edit made quite clear, you only want a None as the result when both the input options are None. In this case I don't think you'll get anything better in terms of simplicity than what you already use. I could shorten it a bit but overall this is just the same:
(one ++ two).reduceOption(_ + _)
obligatory scalaz answer is to use the scalaz Option monoid:
scala> one |+| two
res0: Option[Int] = Some(3)
It will do what you want with respect to None:
scala> two |+| None
res1: Option[Int] = Some(2)
scala> none[Int] |+| none[Int]
res2: Option[Int] = None
That none method is a method from scalaz which helps with type inference because instead of returning None <: Option[Nothing] it returns a Option[Int], there is a similar method from Some which returns an Option[A] for any given A instead of a Some[A]:
scala> 1.some |+| 2.some
res3: Option[Int] = Some(3)
How about:
one.map(_ + two.getOrElse(0)).orElse(two)
You could try this:
for( x <- one.orElse(Some(0)); y <- two.orElse(Some(0))) yield x+y

Finding Scaladoc help, reduceLeft

Say, i am looking to better understand what reduceLeft method does when applied on a Array[String]
The scaladoc says:
Ok, i must ask again, what does this method do? And what's more important, if i can't rely on scaladoc to tell me that, where can i find out?
Yeah - that Scaladoc entry could probably be more helpful.
Another useful source of documentation is the Scala Documentation site, which has this to say about reduceLeft:
xs reduceLeft op
Apply binary operation op between successive elements of non-empty collection xs, going left to right.
So what it does is reduce a collection to a single value by successively applying a binary operator. Some examples:
scala> Array(1, 2, 3, 4) reduceLeft (_ + _)
res2: Int = 10
scala> Array("foo", "bar", "baz") reduceLeft (_ + _)
res3: String = foobarbaz

count occurrences of elements [duplicate]

This question already has answers here:
Scala how can I count the number of occurrences in a list
(17 answers)
Closed 5 years ago.
Counting all elements in a list is a one-liner in Haskell:
count xs = toList (fromListWith (+) [(x, 1) | x <- xs])
Here is an example usage:
*Main> count "haskell scala"
[(' ',1),('a',3),('c',1),('e',1),('h',1),('k',1),('l',3),('s',2)]
Can this function be expressed so elegantly in Scala as well?
scala> "haskell scala".groupBy(identity).mapValues(_.size).toSeq
res1: Seq[(Char, Int)] = ArrayBuffer((e,1), (s,2), (a,3), ( ,1), (l,3), (c,1), (h,1), (k,1))
Recall group from the Data.List library,
group :: [a] -> [[a]]
giving us:
map (head &&& length) . group . sort
a list-friendly and relatively "naive" implementation.
Another implementation:
def count[A](xs: Seq[A]): Seq[(A, Int)] = xs.distinct.map(x => (x, xs.count(_ == x)))
Going for a literal translation, let's try this:
// Implementing this one in Scala
def fromSeqWith[A, B](s: Seq[(A, B)])(f: (B, B) => B) =
s groupBy (_._1) mapValues (_ map (_._2) reduceLeft f)
def count[A](xs: Seq[A]) = fromSeqWith(xs map (_ -> 1))(_+_).toSeq
Scala's groupBy makes this more complex than it needs to be -- there have been calls for groupWith or groupInto, but they didn't make Odersky's standard for standard library inclusion.

Elegant way to express xs.sort.head

Several combinations of methods on a collection can be expressed more succinctly in Scala. For example, xs.filter(f).headOption can be expressed as xs.find(f), and xs.map.filter can usually be better expressed through xs.collect.
I find myself writing xs.sortWith(f).head, and this feels to me like the sort of thing that could be expressed as a single method, "find me the least element in this collection, according to this sorting function".
However, I can't see any obvious methods on Seq or TraversableLike. Is there a single method that captures my intent, or is .sort.head the more elegant way to find the "least" element?
scala> val xs = List("hello", "bye", "hi")
xs: List[java.lang.String] = List(hello, bye, hi)
scala> xs.sortWith(_.length < _.length).head
res10: java.lang.String = hi
scala> xs.min(Ordering.fromLessThan[String](_ > _))
res11: java.lang.String = hi
scala> xs.min(Ordering.by((_: String).length))
res12: java.lang.String = hi
scala> xs.minBy(_.length)
res13: java.lang.String = hi