Can I overload parenthesis in Scala? - scala

Trying to figure out out how to overload parenthesis on a class.
I have this code:
class App(values: Map[String,String])
{
// do stuff
}
I would like to be able to access the values Map this way:
var a = new App(Map("1" -> "2"))
a("1") // same as a.values("1")
Is this possible?

You need to define an apply method.
class App(values: Map[String,String]) {
def apply(x:String) = values(x)
// ...
}

For completeness, it should be said that your "apply" can take multiple values, and that "update" works as the dual of "apply", allowing "parentheses overloading" on the left-hand-side of assignments
Class PairMap[A, B, C]{
val contents: mutable.Map[(A,B), C] = new mutable.Map[(A, B), C]();
def apply(a:A, b:B):C = contents.get((a, b))
def update(a:A, b:B, c:C):Unit = contents.put((a, b), c)
}
val foo = new PairMap[String, Int, Int]()
foo("bar", 42) = 6
println(foo("bar", 42)) // prints 6
The primary value of all this is that it keeps people from suggesting extra syntax for things that had to be special-cased in earlier C-family languages (e.g. array element assignment and fetch). It's also handy for factory methods on companion objects. Other than that, care should be taken, as it's one of those things that can easily make your code too compact to actually be readable.

As others have already noted, you want to overload apply:
class App(values: Map[String,String]) {
def apply(s: String) = values(s)
}
While you're at it, you might want to overload the companion object apply also:
object App {
def apply(m: Map[String,String]) = new App(m)
}
Then you can:
scala> App(Map("1" -> "2")) // Didn't need to call new!
res0: App = App#5c66b06b
scala> res0("1")
res1: String = 2
though whether this is a benefit or a confusion will depend on what you're trying to do.

I think it works using apply : How does Scala's apply() method magic work?

Related

Assign values of a tuple to single variables in Scala

is there a nice possibilyt to assign the values of a tuple to single variables? Here is what i want to do but it throws an error:
var a : Int = _
var b : Int = _
def init() {
(a,b) = getTuple() // returns (Int, Int)
}
def someFunction = {
// use a here
}
def someOtherFunction = {
// use b here
}
Error: ';' expected but '=' found.
(a, b) = getTuple()
Do i really have to do this ._1 and ._2 thing?
val tuple = getTuple() // returns (Int, Int)
a = tuple._1
b = tuple._2
Thanks for answering.
As you can see in Section 6.15 Assignments of the Scala Language Specification, the lefthand-side of an assignment expression must be either a bare identifier:
foo = ???
// either an assignment to a local mutable `var` or syntactic sugar for:
foo_=(???)
a member access:
foo.bar = ???
// syntactic sugar for:
foo.bar_=(???)
or a method call:
foo(bar) = ???
// syntactic sugar for:
foo.update(bar, ???)
Pattern Matching is only available for value definitions (see Section 4.1 Value Declarations and Definitions) and variable definitions (see Section 4.2 Variable Declarations and Definitions).
So, both of the following would be legal:
var (a, b) = getTuple()
val (a, b) = getTuple()
By the way, there are a number of highly non-idiomatic things in your code:
It is highly unusual to pass an empty argument list to a method call. Normally, methods that have no parameters should have no parameter lists instead of an empty parameter list. The only exception are methods that have side-effects, where the empty parameter list serves as kind of a "warning flag", but methods which have side-effects are highly non-idiomatic as well. So, getTuple should be defined and called like this:
def getTuple = ???
getTuple
instead of
def getTuple() = ???
getTuple()
On the other hand, if the method does have side-effects, it shouldn't be called getTuple because that implies that the method "gets" something, and there is no indication that it also changes something.
In Scala, getters and setters are not called getFoo and setFoo but rather foo and foo_=, so the method should rather be called tuple.
Mutable variables are highly non-idiomatic as well, they should probably rather be vals.
Tuple destructuring is an opaque call to unapply method of TupleN[T1, ..., Tn] companion object, aka extractor object.
As the documentation suggests, one can only have a variable initialization with an extractor object, but not assignment.
So, the only possible way is to use it like this:
def getTuple = (1,2)
def main() = {
val (a,b) = getTuple
// use a,b
}
The fact that you use a var may be the sign you have a design flaw. Try to refactor your code or specify the exact problem you're trying to solve with the var to justify its usage (although what you're trying to do with extractor is still impossible)

Scala covariant doc example allows apples and oranges

See this implementation follows the upper bound example http://docs.scala-lang.org/tutorials/tour/upper-type-bounds.html
class Fruit(name: String)
class Apple (name: String) extends Fruit(name)
class Orange(name: String) extends Fruit(name)
class BigOrange(name:String) extends Orange(name)
class BigFLOrange(name:String) extends BigOrange(name)
// Straight from the doc
trait Node[+B ] {
def prepend[U >: B ](elem: U)
}
case class ListNode[+B](h: B, t: Node[B]) extends Node[B] {
def prepend[U >:B ](elem: U) = ListNode[U](elem, this)
def head: B = h
def tail = t
}
case class Nil[+B ]() extends Node[B] {
def prepend[U >: B ](elem: U) = ListNode[U](elem, this)
}
But this definition seems to allow multiple unrelated things in the same container
val f = new Fruit("fruit")
val a = new Apple("apple")
val o = new Orange("orange")
val bo = new BigOrange("big orange")
val foo :ListNode[BigOrange] = ListNode[BigOrange](bo, Nil())
foo.prepend(a) // add an apple to BigOrangeList
foo.prepend(o) // add an orange to BigOrangeList
val foo2 : ListNode[Orange] = foo // and still get to assign to OrangeList
So I am not sure this is a great example in the docs. And, question, how doe I modify the constraints so that..this behaves more like a List?
User #gábor-bakos points out that I am confusing invariance with covariance. So I tried the mutable list buffer. It does not later allow apple to be inserted into an Orange list Buffer, but it is not covariant
val ll : ListBuffer[BigOrange]= ListBuffer(bo)
ll += bo //good
ll += a // not allowed
So..can my example above (ListNode) be modified so that
1. it is covariant (it already is)
2 It is mutable, but mutable like the ListBuffer example (will not later allow apples to be inserted into BigOrange list
A mutable list cannot/should not be covariant in its argument type.
Exactly because of the reason you noted.
Suppose, you could have a MutableList[Orange], that was a subclass of a MutableList[Fruit]. Now, there is nothing that would prevent you from making a function:
def putApple(fruits: MutableList[Fruit], idx: Int) =
fruits(idx) = new Apple
You can add Apple to the list of Fruits, because Apple is a Fruit, nothing wrong with this.
But once you have a function like that, there is no reason you can't call it like this:
val oranges = new MutableList[Orange](new Orange, new Orange)
putApple(oranges, 0)
This will compile, since MutableList[Orange] is a subclass of MutableList[Fruit]. But now:
val firstOrange: Orange = oranges(0)
will crash, because the first element of oranges is actually an Apple.
For this reason, mutable collections have to be invariant in the element type (to answer the question you asked in the comments, to make the list invariant remove the + before B, and also get rid of the type parameter in prepend. It should just be def pretend(elem: B)).
How to get around it? The best solution is to simply not use mutable collections. You should not need them in 99% or real life scala code. If you think you need one, there is a 99% you are doing something wrong.
The major thing that you are probably missing is that prepend does not modify a list. In the line val foo2 : ListNode[Orange] = foo the list foo is still of type ListNode[BigOrange] and given covariance of parameters this assignment is valid (and there is nothing particularly awkward about it). Compiler will prevent you from assigning Fruits to Oranges (in this case assigning an Apple to an Orange is hazardous) but you have to save modified lists beforehand:
val foo: ListNode[Fruit] = ListNode[BigOrange](bo, Nil()).prepend(a).prepend(o)
val foo2: ListNode[Orange] = foo // this is not valid
Moreover your Node definition lacks return type for prepend - thus compiler infers wrong return type (Unit instead of ListNode[U]).
Here's fixed version:
trait Node[+B] {
def prepend[U >: B ](elem: U): Node[U]
}

Scala: Preference among overloaded methods with implicits, currying and defaults

The following simple piece of code fails to compile:
object O {
def apply(s:String, o:Int=5)(implicit i:String) = {
println("am first");
s
}
def apply(s:String)(o:Boolean*) = {
println("am second");
o
}
}
object Main extends App {
implicit val myS = "foo"
O("test")
}
The error being
error: missing arguments for method apply in object O;
follow this method with `_' if you want to treat it as a partially applied function
O("test")
^
one error found
This appears to be because the compiler prefers the second apply. But why is this? Especially considering that the conditions for applying the first apply are satisfied? If I delete the second apply the piece of code compiles fine.
Are there any way to "guide" the compiler towards compiling this correctly? Or am I forced to create two different method names?
You're right that it is possible for the Scala compiler to be smarter. The problem is that noone has wanted to come up with the new specification for this. It'll be very complicated.
There are ways to get around this limitation.
1. replace overloading with pattern matching within apply to choose one of the two functions
def apply(s: String, i: Option[Int] = None) = {
i match {
case Some(n) => // call the 1st
case None => // call the 2nd
}
}
Then:
apply("test", Some(5)) => ... // if we want the first
apply("test") => ... // if we want the second
2. use overloading but with different parameter names for the two functions:
def apply(apple: String, o: Int = 5)(implicit i: String)
def apply(banana: String)(o: Boolean*)
Then:
apply(apple = "test") // if we want the first
apply(banana = "test") // if we want the second
Let's regard this situation without implicits
object O {
def apply(s: String, o: Int = 5) = {
println("am first")
}
def apply(s: String) = {
println("am second")
}
}
In this situation O("test") will be compiled with second apply, so you can't use default parameters in this situation. Implicits changes nothing here. If you'll explicitly provide Int parameter, you cod will compile with first apply.

Scala child listbuffer returned as parent listbuffer

I have started working on scala now. And come to a point where I want to use Inheritance correctly.
I am stuck at once place. I have tried to read docs and other information online. but I seems like I am stuck.
Please look at this and tell me if you have faced this in the past and whether I am doing something really really wrong.
So, this is my method:
def getFacethierarchy): ListBuffer[BaseClass] = {
val obj: Childclass = new ChildClass(1, "2")
val list: ListBuffer[ChildClass] = ListBuffer[ChildClass]()
list += obj
list
}
class BaseClass(var id: Int){
}
class ChildClass(id: Int, var name: String) extends BaseClass(id){
}
Now scala Is not allowing me to return a ChildClass instance.
In Java, this would work (Child is a type of Parent)
I tried to change my method signature to return "Any".
I am not sure what I am going wrong with.
Please help, if possible.
update:
To be more specific to what I am doing, I have updated the code snippet.
ListBuffer[ChildClass] is not a subtype of ListBuffer[BaseClass] because ListBuffer being a mutable data structure, it would break the type-safety.
You want to avoid something like:
val l : ListBuffer[Int] = ListBuffer[Int](1, 2, 3)
val l2 :ListBuffer[Any] = l
l2(0) = 2.54
What you can do is to simply create a ListBuffer[BaseClass]:
def getFacethierarchy): ListBuffer[BaseClass] = {
val obj: Chlidclass = new ChildClass(1, "2")
ListBuffer[BaseClass](obj)
}
The problem stems from the fact that ListBuffer is invariant, not covariant (no + before T). It cannot be covariant. For this reason, the ListBuffer[ChildClass] is not a subtype of ListBuffer[BaseClass], even if ChildClass is a subtype of BaseClass.
You can use existential types (: ListBuffer[T] forSome {type T <: BaseClass} (hope I used the correct syntax)), or provide an additional type parameter to the method you want to use (yourMethod[T <: BaseClass]: ListBuffer[T]). If you want "MyTypes" (might be, hard to tell without further details): Scala do not support it.
Taking a closer look at your code, you might prefer to return a List[BaseClass] instead, which is covariant, so you could write:
def getFacethierarchy: List[BaseClass] = {
val obj: Chlidclass = new ChildClass(1, "2")
val list: ListBuffer[ChildClass] = ListBuffer[ChildClass]()
list += obj
list.toList
}

How to write this three-liner as a one-liner?

I like the way, you can write one-liner-methods in Scala, e.g. with List(1, 2, 3).foreach(..).map(..).
But there is a certain situation, that sometimes comes up when writing Scala code, where things get a bit ugly. Example:
def foo(a: A): Int = {
// do something with 'a' which results in an integer
// e.g. 'val result = a.calculateImportantThings
// clean up object 'a'
// e.g. 'a.cleanUp'
// Return the result of the previous calculation
return result
}
In this situation we have to return a result, but can not return it directly after the calculation is done, because we have to do some clean up before returning.
I always have to write a three-liner. Is there also a possibility to write a one-liner to do this (without changing the class of A, because this may be a external library which can not be changed) ?
There are clearly side-effects involved here (otherwise the order of invocation of calculateImportantThings and cleanUp wouldn't matter) so you would be well advised to reconsider your design.
However, if that's not an option you could try something like,
scala> class A { def cleanUp {} ; def calculateImportantThings = 23 }
defined class A
scala> val a = new A
a: A = A#927eadd
scala> (a.calculateImportantThings, a.cleanUp)._1
res2: Int = 23
The tuple value (a, b) is equivalent to the application Tuple2(a, b) and the Scala specification guarantees that its arguments will be evaluated left to right, which is what you want here.
This is a perfect use-case for try/finally:
try a.calculateImportantThings finally a.cleanUp
This works because try/catch/finally is an expression in scala, meaning it returns a value, and even better, you get the cleanup whether or not the calculation throws an exception.
Example:
scala> val x = try 42 finally println("complete")
complete
x: Int = 42
There is, in fact, a Haskell operator for just such an occasion:
(<*) :: Applicative f => f a -> f b -> f a
For example:
ghci> getLine <* putStrLn "Thanks for the input!"
asdf
Thanks for the input!
"asdf"
All that remains then is to discover the same operator in scalaz, since scalaz usually replicates everything that Haskell has. You can wrap values in Identity, since Scala doesn't have IO to classify effects. The result would look something like this:
import scalaz._
import Scalaz._
def foo(a: A): Int =
(a.calculateImportantThings.pure[Identity] <* a.cleanup.pure[Identity]).value
This is rather obnoxious, though, since we have to explicitly wrap the side-effecting computations in Identity. Well the truth is, scalaz does some magic that implicitly converts to and from the Identity container, so you can just write:
def foo(a: A): Int = Identity(a.calculateImportantThings) <* a.cleanup()
You do need to hint to the compiler somehow that the leftmost thing is in the Identity monad. The above was the shortest way I could think of. Another possibility is to use Identity() *> foo <* bar, which will invoke the effects of foo and bar in that order, and then produce the value of foo.
To return to the ghci example:
scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._
scala> val x : String = Identity(readLine) <* println("Thanks for the input!")
<< input asdf and press enter >>
Thanks for the input!
x: String = asdf
Maybe you want to use a kestrel combinator? It is defined as follows:
Kxy = x
So you call it with the value you want to return and some side-effecting operation you want to execute.
You could implement it as follows:
def kestrel[A](x: A)(f: A => Unit): A = { f(x); x }
... and use it in this way:
kestrel(result)(result => a.cleanUp)
More information can be found here: debasish gosh blog.
[UPDATE] As Yaroslav correctly points out, this is not the best application of the kestrel combinator. But it should be no problem to define a similar combinator using a function without arguments, so instead:
f: A => Unit
someone could use:
f: () => Unit
class Test {
def cleanUp() {}
def getResult = 1
}
def autoCleanup[A <: Test, T](a: A)(x: => T) = {
try { x } finally { a.cleanUp }
}
def foo[A <: Test](a:A): Int = autoCleanup(a) { a.getResult }
foo(new Test)
You can take a look at scala-arm project for type class based solution.
Starting Scala 2.13, the chaining operation tap can be used to apply a side effect (in this case the cleanup of A) on any value while returning the original value untouched:
def tap[U](f: (A) => U): A
import util.chaining._
// class A { def cleanUp { println("clean up") } ; def calculateImportantThings = 23 }
// val a = new A
val x = a.calculateImportantThings.tap(_ => a.cleanUp)
// clean up
// x: Int = 23
In this case tap is a bit abused since we don't even use the value it's applied on (a.calculateImportantThings (23)) to perform the side effect (a.cleanUp).