List#() on Intermediate List - scala

I can get the index = 2 item from a List using apply.
scala> List(1,2,3).apply(2)
res3: Int = 3
scala> val x = List(1,2,3)
x: List[Int] = List(1, 2, 3)
scala> x(2)
res4: Int = 3
scala> List(1,2,3).apply(2)
res5: Int = 3
But, why can't I do the following?
scala> List(1,2,3).(2)
<console>:1: error: identifier expected but '(' found.
List(1,2,3).(2)
^

you don't need .
scala> List(1,2,3)(2)
res1: Int = 3

Related

Ommiting parenthesis in adding elements to List

I'm trying to add element to a List[String] while omitting annoying parenthesis. I tried this:
object Main extends App {
val l = List("fds")
val xs1: List[String] = l.+:("123") // ok
val xs2: List[String] = l +: "123" // compile-error
}
DEMO
Why is omitting parenthesis causing compile-error? These assignments look the same to me. What is the difference?
It's happening because of right associative methods.
scala> val l = List("abc")
l: List[String] = List(abc)
scala> "efg" +: l
res3: List[String] = List(efg, abc)
Read more here What good are right-associative methods in Scala?
Error case
scala> val l = List(1, 2, 3)
l: List[Int] = List(1, 2, 3)
scala> 4 +: l
res1: List[Int] = List(4, 1, 2, 3)
scala> l +: 1
<console>:13: error: value +: is not a member of Int
l +: 1
^
Because +: is right associative. Method +: is getting invoked on Int instead of list
In order to make it work we can explicitly invoke method on list without the special operator syntax
scala> val l = List(1, 2, 3)
l: List[Int] = List(1, 2, 3)
scala> l.+:(1)
res4: List[Int] = List(1, 1, 2, 3)
Above case works because its normal method invocation.

How to use previous expression's result in Scala REPL?

// when in Scala REPL
scala> 1
res0: Int = 1
How can I reuse an expression's result in another expression?
For example:
scala> 1
res0: Int = 1
scala> the_previous_expression + 1
// = 2
You can reuse the previous expression's result by looking its REPL output on the next line, the word starting with res.
// when in Scala REPL
scala> 1
res0: Int = 1 // <-- res0 is the handle that you can use
For example:
scala> 1
res0: Int = 1
scala> res0 + 1
res1: Int = 2
scala> res1 + 1
res2: Int = 3
// and so on
You can also use it with others:
scala> () => "hey!" // anonymous function
res0: () => String = $$Lambda$1104/1658578510#6cff61fc
scala> res0()
res1: String = hey

What are the equivalent Option's sequence and traverse methods for \/?

on scalaz 7.2.6, this works:
// import scalaz.syntax.traverse._
List(1.some, 2.some, 3.some).sequence
res12: Option[List[Int]] = Some(List(1, 2, 3))
List(1.some, none, 3.some).sequence
res13: Option[List[Int]] = None
def doubleSmall(x: Int) = if (x < 30) (x * 2).some else none
List(1,2,3).traverse(doubleSmall)
res15: Option[List[Int]] = Some(List(2, 4, 6))
The following code does not compile. Is there an equivalent of Option's sequence and traverse methods for \/?
List(1.right, 2.right, 3.right).sequence
expecting something like: List(1, 2, 3).right
List(1.right, "error2".left, "error3".left).sequence
expecting something like: Seq("error2", "error3").left
val doubleSmall(x: Int) = if (x < 30) (x * 2).right else "error".left
List(1,2,3).traverse(doubleSmall)
You're looking for sequenceU and traverseU:
scala> List[\/[String, Int]](1.right, 2.right, 3.right).sequenceU
res3: scalaz.\/[String,List[Int]] = \/-(List(1, 2, 3))
scala> List(1.right, 2.right, 3.right, "a".left).sequenceU
res4: scalaz.\/[String,List[Int]] = -\/(a)
Note that the first example needs a type hint so that it can pick up the proper implicit Unapply[Applicative, \/[String, Int]].
scala> List(1,2,3).traverseU(doubleSmall)
res9: scalaz.\/[String,List[Int]] = \/-(List(2, 4, 6))

`val (A) = (3)` is correct, but `val (A,B)=(2,3)` can't be compiled, why?

val A = 3
val (A) = (3)
Both correct. But:
val (A,B) = (2,3)
can't be compiled:
scala> val (A,B) = (2,3)
<console>:7: error: not found: value A
val (A,B) = (2,3)
^
<console>:7: error: not found: value B
val (A,B) = (2,3)
^
Why?
In the second code snippet, it using pattern matching to do assessment.
It is translated to the follow code:
val Tuple(A, B) = Tuple2(2,3)
When Scala is doing pattern matching, variable starts with a upper case in the pattern is considered as an constant value (or singleton Object), so val (a, b) = (2, 3) works but not val (A, B) = (2, 3).
BTW, your first code snippet does not using pattern matching, it's just an ordinary variable assignment.
If you using Tuple1 explicitly, it will have same error.
scala> val Tuple1(Z) = Tuple1(3)
<console>:7: error: not found: value Z
val Tuple1(Z) = Tuple1(3)
Here is some interesting example:
scala> val A = 10
A: Int = 10
scala> val B = 20
B: Int = 20
scala> val (A, x) = (10, 20)
x: Int = 20
scala> val (A, x) = (10, 30)
x: Int = 30
scala> val (A, x) = (20, 20)
scala.MatchError: (20,20) (of class scala.Tuple2$mcII$sp)
at .<init>(<console>:9)
at .<clinit>(<console>)

What is the difference between val b=a (a is an Array) and val b=a.clone()?

I am reading scaladocs and just wondering difference between direct assignment and .clone method.
val a=Array(1,2,3,4,5)
case 1:
val b=a
case 2 :
val b=a.clone()
Consider this:
scala> val a=Array(1,2,3,4,5)
a: Array[Int] = Array(1, 2, 3, 4, 5)
scala> val b = a
b: Array[Int] = Array(1, 2, 3, 4, 5)
scala> val c = a.clone()
c: Array[Int] = Array(1, 2, 3, 4, 5)
scala> b(0) = 0
scala> c(1) = 1
scala> a
res2: Array[Int] = Array(0, 2, 3, 4, 5)
scala> b
res3: Array[Int] = Array(0, 2, 3, 4, 5)
scala> c
res4: Array[Int] = Array(1, 1, 3, 4, 5)
As you can see, when you do val b = a, then a and b point to the same object. When the object is changed, the change will be seen by both.
On the other hand, when you clone the array, you produce a new array with the same content. Changing this new array does not change the old one.
I believe case 1 just sets the reference of a to b while case 2 creates an entirely new array that is a copy of a and putting the value in b.
In other words if you in case a edit the a array the b array will also be edited this is not the case in case 2
Here is an answer in code:
scala> val a = Array(1,2,3,4,5)
scala> a.hashCode()
res12: Int = 1382155266
scala> val b = a
scala> b.hashCode()
res13: Int = 1382155266
scala> val c = a.clone()
scala> c.hashCode()
res14: Int = 2062756135
scala> a eq b
res15: Boolean = true
scala> a eq c
res16: Boolean = false
scala> b eq c
res17: Boolean = false
In case 1, both reference leads to the same object while in the second case, a new object is created and a and b do not reference the same object.