Scalaz - combining List and State Monad in for comprehension - scala

I am planning to start using Monadic style in my Scala code for, amongst others, threading state. Here's a simplified example of combining 3 monadic functions (and caring only about the side effects)
import scalaz._
import Scalaz._
object MonadTest {
def adder(i: Int) = State[String, Int] ({str: String => (str + i.toString + " ", i) })
val oneTwoThreeMonad = for {
m1 <- adder(1)
m2 <- adder(2)
m3 <- adder(3)
} yield m3
oneTwoThreeMonad("start: ")._1 //String = "start: 1 2 3 "
}
This all is pretty self-explanatory and works as expected. But for this approach to be really useful to me I would like to be able to combine it with List for-comprehension. Here's a bit of (not working) code to show what I mean:
val list = List(1, 2, 3)
val oneTwoThreeBis = for {
i <- list
mx <- adder(i)
} yield mx
Basically I would like to be able to combine monads based on arguments from a List - run the monadic function on each of the elements of the list and accumulate the side-effects as I go. I understand the example syntax doesn't work and I see why it doesn't - I'm just looking for a clean, elegant equivalent.
I am pretty sure it is possible to achieve this using scalaz monad transformers, more specifically with StateT but I'm not really sure how one would go about doing it.
PS. I'm using Scalaz 7.0-M3, so the syntax might be a little different from the most common 6.x.

I'm not sure I understand exactly what you're looking for, but it sounds like you want something more like traverse here (where traverse is a more general version of Haskell's mapM):
import scalaz._, Scalaz._
def adder(i: Int) = State[String, Int](str => (str + i.toString + " ", i))
List(1, 2, 3).traverseS(adder)("start: ")._1
This will print the following, as expected:
res0: String = "start: 1 2 3 "
Note that I'm using traverseS (where the S stands for State) to avoid having to write out the rather messy type parameter, but traverse is more generally useful anytime you want to map a monadic function over something traversable.
I'm happy to give a StateT example if this isn't what you wanted, but that's going to end up with you having something of type List[(String, Int)].

Related

How to create a nested ListBuffer within another ListBuffer n times in Scala?

I have an emptyListBuffer[ListBuffer[(String, Int)]]() initialized like so, and given a number n, I want to fill it with n ListBuffer[(String, Int)].
For example, if n=2 then I can initialize two ListBuffer[(String, Int)] within ListBuffer[ListBuffer[(String, Int)]]() if that makes any sense. I was trying to loop n times and use the insertAll function to insert an empty list but I didn't work.
use fill
fill is a standard Scala library function in order to fill a data structure with predefined elements. Its quite handy and save lot of typing.
ListBuffer.fill(100)(ListBuffer("Scala" -> 1))
Scala REPL
scala> import scala.collection.mutable._
import scala.collection.mutable._
scala> ListBuffer.fill(100)(ListBuffer("Scala" -> 1))
res4: scala.collection.mutable.ListBuffer[scala.collection.mutable.ListBuffer[(String, Int)]] = ListBuffer(ListBuffer((Scala,1)), ListBuffer((Scala,1)), ListBuffer((Scala,1)), ListBuffer((Scala,1)), ListBuffer((Scala,1)) ...
fill implementation in Standard library
def fill[A](n: Int)(elem: => A): CC[A] = {
val b = newBuilder[A]
b.sizeHint(n)
var i = 0
while (i < n) {
b += elem
i += 1
}
b.result()
}
The above implementation is for one dimensional data structure.
General suggestions
Looks like you are using Scala like the Java way. This is not good. Embrace functional way for doing things for obvious benefits.
Use immutable collections like List, Vector instead of mutable collections. Do not use mutable collections until and unless you have string reason for it.
Same thing can be done using immutable List
List.fill(100)(List("scala" -> 1))
scala -> 1 is same as ("scala", 1)

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.

Representation of a Seq with only one element?

Often I find myself passing a Seq with just one element to methods like this:
def myMethod(myList: Seq[Int]) = { ... }
Usually I do this like so:
myMethod(List(42))
But it occurs to me that this might not be the most elegant way, and if there's one thing about Scala that I love, it is its capability of blowing my mind by cutting down on characters used when I thought it impossible.
So, is there a shorter or more elegant representation of a single-item Seq than List(42)?
I can think of a couple worse options!
42 to 42
42 :: List()
Probably the shortest built-in way is to just use Seq companion object's apply and write
myMethod(Seq(42))
That apply function returns the default Seq implementation, that is A List and is therefore equivalent to using List(42).
I'm not sure there's any Seq implementation with a shorter name, but you can surely implement your own or simply import Seq (or List) while aliasing the name:
scala> import scala.collection.{Seq => S}
scala> S(42)
res0: Seq[Int] = List(3)
A shorter usage syntax may be obtained with this implicit,
implicit def SingletonSeq(i: Int) = Seq(i)
Hence
def myMethod(myList: Seq[Int]) = myList.size
myMethod(42)
res: 1

Cross product of two Strings

I am just starting out in Scala and for my first project, I am writing a Sudoku solver. I came across a great site explaining Sudoku and how to go about writing a solver: http://norvig.com/sudoku.html and from this site I am trying to create the corresponding Scala code.
The squares of a Sudoku grid are basically the cross product of the row name and the column name, this can be generated really easily in Python using a list comprehension:
# cross("AB", "12") = ["A1", "A2", "B1", "B2"]
def cross(A, B):
"Cross product of elements in A and elements in B."
return [a+b for a in A for b in B]
It took me awhile to think about how to do this elegantly in Scala, and this is what I came up with:
// cross("AB", "12") => List[String]("A1", "A2", "B1", "B2")
def cross(r: String, c: String) = {
for(i <- r; j <- c) yield i + "" + j
}.toList
I was just curious if there is a better way to doing this in Scala? It would seem much cleaner if I could do yield i + j but that results in an Int for some reason. Any comments or suggestions would be appreciated.
Yes, addition for Char is defined by adding their integer equivalents. I think your code is fine. You could also use string interpolation, and spare the toList (you will get an immutable indexed sequence instead which is just fine):
def cross(r: String, c: String) = for(i <- r; j <- c) yield s"$i$j"
EDIT
An IndexedSeq is at least as powerful as List. Just check your successive usage of the result. Does it require a List? E.g. do you want to use head and tail and pattern match with ::. If not, there is no reason why you should need to enforce List. If you use map and flatMap on the input arguments instead of the syntactic sugar with for, you can use the collection.breakOut argument to directly map to a List:
def cross(r: String, c: String): List[String] =
r.flatMap(i => c.map(j => s"$i$j"))(collection.breakOut)
Not as pretty, but faster than an extra toList.

What is the accepted/recommended syntax for Scala code with lots of method-chaining?

In Scala I tend to favour writing large chained expressions over many smaller expressions with val assignments. At my company we've sort of evolved a style for this type of code. Here's a totally contrived example (idea is to show an expression with lots of chained calls):
import scala.util.Random
val table = (1 to 10) map { (Random.nextInt(100), _) } toMap
def foo: List[Int] =
(1 to 100)
.view
.map { _ + 3 }
.filter { _ > 10 }
.flatMap { table.get }
.take(3)
.toList
Daniel Spiewak's Scala Style Guide (pdf), which I generally like, suggests the leading dot notation in the chained method calls may be bad (see doc: Method Invocation / Higher-Order Functions), though it doesn't cover multi-line expressions like this directly.
Is there another, more accepted/idiomatic way to write the function foo above?
UPDATE: 28-Jun-2011
Lots of great answers and discussion below. There doesn't appear to be a 100% "you must do it this way" answer, so I'm going to accept the most popular answer by votes, which is currently the for comprehension approach. Personally, I think I'm going to stick with the leading-dot notation for now and accept the risks that come with it.
The example is slightly unrealistic, but for complex expressions, it's often far cleaner to use a comprehension:
def foo = {
val results = for {
x <- (1 to 100).view
y = x + 3 if y > 10
z <- table get y
} yield z
(results take 3).toList
}
The other advantage here is that you can name intermediate stages of the computation, and make it more self-documenting.
If brevity is your goal though, this can easily be made into a one-liner (the point-free style helps here):
def foo = (1 to 100).view.map{3+}.filter{10<}.flatMap{table.get}.take(3).toList
//or
def foo = ((1 to 100).view map {3+} filter {10<} flatMap {table.get} take 3).toList
and, as always, optimise your algorithm where possible:
def foo = ((1 to 100).view map {3+} filter {10<} flatMap {table.get} take 3).toList
def foo = ((4 to 103).view filter {10<} flatMap {table.get} take 3).toList
def foo = ((11 to 103).view flatMap {table.get} take 3).toList
I wrap the entire expression into a set of parenthesis to group things and avoid dots if possible,
def foo: List[Int] =
( (1 to 100).view
map { _ + 3 }
filter { _ > 10 }
flatMap { table.get }
take(3)
toList )
Here's how extempore does it. You can't go wrong.
(specMember
setInfo subst(env, specMember.info.asSeenFrom(owner.thisType, sym.owner))
setFlag (SPECIALIZED)
resetFlag (DEFERRED | CASEACCESSOR | ACCESSOR | LAZY)
)
Authentic compiler source!
I prefer lots of vals:
def foo = {
val range = (1 to 100).view
val mappedRange = range map { _+3 }
val importantValues = mappedRange filter { _ > 10 } flatMap { table.get }
(importantValues take 3).toList
}
Because I don't know what you want to purpose with your code, I chose random names for the vals.
There is a big advantage to choose vals instead of the other mentioned solutions:
It is obvious what your code does. In your example and in the solutions mentioned in most other answers anyone does not know at first sight what it does. There is too much information in one expression. Only in a for-expression, mentioned by #Kevin, it is possible to choose telling names but I don't like them because:
They need more lines of code
They are slower due to pattern match the declared values (I mentioned this here).
Just my opinion, but I think they look ugly
My rule: if the expression fits on a single (80-120 character) line, keep it on one line and omit the dots wherever possible:
def foo: List[Int] =
(1 to 100).view map { _ + 3 } filter { _ > 10 } flatMap table.get take 3 toList
As Kevin pointed out, the point-free style may improve brevity (but could harm readability for developers not familiar with it):
def foo: List[Int] =
(1 to 100).view map{3+} filter{10<} flatMap table.get take 3 toList
The leading dot notation is perfectly acceptable if you need to separate the expression over multiple lines due to length. Another reason to use this notation is when the operations need individual comments. If you need to spread an expression over multiple lines, due to its length or the need to comment individual operations, it's best to wrap the entire expression in parens (as Alex Boisvert suggests. In these situations, each (logical) operation should go on its own line (i.e. each operation goes on a single line, except where multiple consecutive operations can be described succinctly by a single comment):
def foo: List[Int] =
( (1 to 100).view
map { _ + 3 }
filter { _ > 10 }
flatMap table.get
take 3
toList )
This technique avoids potential semicolon inference issues that can arise when using leading dot notation or calling a 0-arg method at the end of the expression.
I usually try to avoid using dot for things like map and filter. So I would probably write it like the following:
def foo: List[Int] =
(1 to 100).view map { x =>
x + 3 } filter { x =>
x > 10 } flatMap { table.get } take(3) toList
The leading dot notation is very readable. I might start using that.