Scala priority of method call on implicit object - scala

Let's say I have the following scala code:
case class Term(c:Char) {
def unary_+ = Plus(this)
}
case class Plus(t:Term)
object Term {
implicit def fromChar(c:Char) = Term(c)
}
Now I get this from the scala console:
scala> val p = +'a'
p: Int = 97
scala> val q:Plus = +'a'
<console>:16: error: type mismatch;
found : Int
required: Plus
val q:Plus = +'a'
^
Because '+' is already present on the Char type, the implicit conversion does not take place, I think. Is there a way to override the default behaviour and apply '+' on the converted Term before applying on the Char type?
(BTW, the example is artificial and I'm not looking for alternative designs. The example is just here to illustrate the problem)

No, there is no way to override the default + operator, not even with an implicit conversion. When it encounters an operator (actually a method, as operators are just plain methods) that is not defined on the receiving object, the compiler will look for an implicit conversion to an object to does provide this operator. But if the operator is already defined on the target object, it will never look up for any conversion, the original operator will always be called.
You should thus define a separate operator whose name will not conflict with any preexisting operator.
UPDATE:
The precise rules that govern implicit conversions are defined in the Scala Language Specification:
Views are applied in three situations.
If an expression e is of type T , and T does not conform to the expressionโ€™s
expected type pt. In this case an implicit v is searched which is applicable to
e and whose result type conforms to pt. The search proceeds as in the case of
implicit parameters, where the implicit scope is the one of T => pt. If such a
view is found, the expression e is converted to v(e).
In a selection e.m with e of type T , if the selector m does not denote a member
of T . In this case, a view v is searched which is applicable to e and whose result
contains a member named m. The search proceeds as in the case of implicit
parameters, where the implicit scope is the one of T . If such a view is found,
the selection e.m is converted to v(e).m.
In a selection e.m(args) with e of type T , if the selector m denotes some member(s) of T , but none of these members is applicable to the arguments args. In
this case a view v is searched which is applicable to e and whose result contains a method m which is applicable to args. The search proceeds as in the
case of implicit parameters, where the implicit scope is the one of T . If such a
view is found, the selection e.m is converted to v(e).m(args).
In other words, an implicit conversion occurs in 3 situations:
when an expression is of type T but is used in a context where the unrelated type T' is expected, an implicit conversion from T to T' (if any such conversion is in scope) is applied.
when trying to access an object's member that does not exists on said object, an implicit conversion from the object into another object that does have this member (if any such conversion is in scope) is applied.
when trying to call a method of an object's with a parameter list that does not match any of the corresponding overloads, the compiler applies an implicit conversion from the object into another object that does have a method of this name and with a compatible parameter list (if any such conversion is in scope).
Note for completeness that this actually applies to more than just methods (inner objects/vals with an apply method are eligible too). Note also that this is the case that Randall Schulz was talking about in his comment below.
So in your case, points (2) and (3) are relevant. Given that you want to define a method named unary_+, which already exists for type Int, case (2) won't kick in. And given that your version has the same parameter list as the built-in Int.unary_+ method (they are both parameterless), point (3) won't kick in either. So you definitly cannot define an implicit that will redefine unary_+.

Related

Why can't the compiler select the correct String.contains method when using this lambda shorthand?

Say I want to check if a string contains any of the letters in "cory":
def hasCory(input: String): Boolean = {
val myName = "cory"
input.exists(myName.contains)
}
The compiler complains with:
error: type mismatch;
found : CharSequence => Boolean
required: Char => Boolean
Scala provides the Char-accepting method I want in StringOps:
But it appears that the compiler cannot see this method unless I change the code to one of:
input.exists(myName.contains(_))
input.exists(c => myName.contains(c))
Instead in the original example it appears to be using Java String's contains method, which indeed does accept a CharSequence:
Is this working as intended? Why can't the compiler see that I want the Char version of contains?
StringOps is an implicit conversion
#inline implicit def augmentString(x: String): StringOps = new StringOps(x)
And implicit conversion are applicable in three cases only:
If an expression ๐‘’ is of type ๐‘‡, and ๐‘‡ does not conform to the expression's expected type pt.
In a selection ๐‘’.๐‘š
with ๐‘’ of type ๐‘‡, if the selector ๐‘š does not denote an accessible member of ๐‘‡.
In a selection ๐‘’.๐‘š(args)
with ๐‘’ of type ๐‘‡, if the selector ๐‘š denotes some member(s) of ๐‘‡, but none of these members is applicable to the arguments args.
When you write myName.contains it's none of the three cases (in particular,
not the 2nd case because contains is an accessible member of String) so StringOps can't be applied and it's String#contains(CharSequence) and type mismatch error.
When you write myName.contains(_) or c => myName.contains(c) it's the 3rd case so StringOps can be applied and it's StringOps#contains(Char) after implicit conversion.
So yes, it's working as intended.

Demystifying a function definition

I am new to Scala, and I hope this question is not too basic. I couldn't find the answer to this question on the web (which might be because I don't know the relevant keywords).
I am trying to understand the following definition:
def functionName[T <: AnyRef](name: Symbol)(range: String*)(f: T => String)(implicit tag: ClassTag[T]): DiscreteAttribute[T] = {
val r = ....
new anotherFunctionName[T](name.toString, f, Some(r))
}
First , why is it defined as def functionName[...](...)(...)(...)(...)? Can't we define it as def functionName[...](..., ..., ..., ...)?
Second, how does range: String* from range: String?
Third, would it be a problem if implicit tag: ClassTag[T] did not exist?
First , why is it defined as def functionName...(...)(...)(...)? Can't we define it as def functionName[...](..., ..., ..., ...)?
One good reason to use currying is to support type inference. Consider these two functions:
def pred1[A](x: A, f: A => Boolean): Boolean = f(x)
def pred2[A](x: A)(f: A => Boolean): Boolean = f(x)
Since type information flows from left to right if you try to call pred1 like this:
pred1(1, x => x > 0)
type of the x => x > 0 cannot be determined yet and you'll get an error:
<console>:22: error: missing parameter type
pred1(1, x => x > 0)
^
To make it work you have to specify argument type of the anonymous function:
pred1(1, (x: Int) => x > 0)
pred2 from the other hand can be used without specifying argument type:
pred2(1)(x => x > 0)
or simply:
pred2(1)(_ > 0)
Second, how does range: String* from range: String?
It is a syntax for defining Repeated Parameters a.k.a varargs. Ignoring other differences it can be used only on the last position and is available as a scala.Seq (here scala.Seq[String]). Typical usage is apply method of the collections types which allows for syntax like SomeDummyCollection(1, 2, 3). For more see:
What does `:_*` (colon underscore star) do in Scala?
Scala variadic functions and Seq
Is there a difference in Scala between Seq[T] and T*?
Third, would it be a problem if implicit tag: ClassTag[T] did not exist?
As already stated by Aivean it shouldn't be the case here. ClassTags are automatically generated by the compiler and should be accessible as long as the class exists. In general case if implicit argument cannot be accessed you'll get an error:
scala> import scala.concurrent._
import scala.concurrent._
scala> val answer: Future[Int] = Future(42)
<console>:13: error: Cannot find an implicit ExecutionContext. You might pass
an (implicit ec: ExecutionContext) parameter to your method
or import scala.concurrent.ExecutionContext.Implicits.global.
val answer: Future[Int] = Future(42)
Multiple argument lists: this is called "currying", and enables you to call a function with only some of the arguments, yielding a function that takes the rest of the arguments and produces the result type (partial function application). Here is a link to Scala documentation that gives an example of using this. Further, any implicit arguments to a function must be specified together in one argument list, coming after any other argument lists. While defining functions this way is not necessary (apart from any implicit arguments), this style of function definition can sometimes make it clearer how the function is expected to be used, and/or make the syntax for partial application look more natural (f(x) rather than f(x, _)).
Arguments with an asterisk: "varargs". This syntax denotes that rather than a single argument being expected, a variable number of arguments can be passed in, which will be handled as (in this case) a Seq[String]. It is the equivalent of specifying (String... range) in Java.
the implicit ClassTag: this is often needed to ensure proper typing of the function result, where the type (T here) cannot be determined at compile time. Since Scala runs on the JVM, which does not retain type information beyond compile time, this is a work-around used in Scala to ensure information about the type(s) involved is still available at runtime.
Check currying:Methods may define multiple parameter lists. When a method is called with a fewer number of parameter lists, then this will yield a function taking the missing parameter lists as its arguments.
range:String* is the syntax for varargs
implicit TypeTag parameter in Scala is the alternative for Class<T> clazzparameter in Java. It will be always available if your class is defined in scope. Read more about type tags.

Higher-kinded type constructors with and without '_'

This signature declares higher-kinded type:
case class MyContainer[A, M[_]](el: M[A])
Now, I can create instance of it:
scala> val mc1 = MyContainer[Int, Option](Some(3))
mc1: MyContainer[Int,Option] = MyContainer(Some(3))
I can also declare MyContainer as:
case class MyContainer[A, M[A]](el: M[A])
which produces same instance as mc1:
mc1: MyContainer[Int,Option] = MyContainer(Some(3))
What is the difference between these approaches and which should be used when?
According to the language specification (ยง4.4 Type Parameters), these are equivalent:
[M[X], N[X]]
[M[_], N[_]] // equivalent to previous clause
This paragraph describes the reasoning behind this syntax:
Higher-order type parameters (the type parameters of a type parameter t) are only visible in their immediately surrounding parameter clause (possibly including clauses at a deeper nesting level) and in the bounds of t. Therefore, their names must only be pairwise different from the names of other visible parameters. Since the names of higher-order type parameters are thus often irrelevant, they may be denoted with a _, which is nowhere visible.
Note that the A in M[A] is ignored in this case. It could be T and it would work as well:
scala> case class MyContainer[A, M[T]](el: M[A])
defined class MyContainer
scala> val mc1 = MyContainer[Int, Option](Some(3))
mc1: MyContainer[Int,Option] = MyContainer(Some(3))
To prevent confusion I would always use [_], or at least not reuse the names.

What is the point of multiple parameter clauses in function definitions in Scala?

I'm trying to understand the point of this language feature of multiple parameter clauses and why you would use it.
Eg, what's the difference between these two functions really?
class WTF {
def TwoParamClauses(x : Int)(y: Int) = x + y
def OneParamClause(x: Int, y : Int) = x + y
}
>> val underTest = new WTF
>> underTest.TwoParamClauses(1)(1) // result is '2'
>> underTest.OneParamClause(1,1) // result is '2'
There's something on this in the Scala specification at point 4.6. See if that makes any sense to you.
NB: the spec calls these 'parameter clauses', but I think some people may also call them 'parameter lists'.
Here are three practical uses of multiple parameter lists,
To aid type inference. This is especially useful when using higher order methods. Below, the type parameter A of g2 is inferred from the first parameter x, so the function arguments in the second parameter f can be elided,
def g1[A](x: A, f: A => A) = f(x)
g1(2, x => x) // error: missing parameter type for argument x
def g2[A](x: A)(f: A => A) = f(x)
g2(2) {x => x} // type is inferred; also, a nice syntax
For implicit parameters. Only the last parameter list can be marked implicit, and a single parameter list cannot mix implicit and non-implicit parameters. The definition of g3 below requires two parameter lists,
// analogous to a context bound: g3[A : Ordering](x: A)
def g3[A](x: A)(implicit ev: Ordering[A]) {}
To set default values based on previous parameters,
def g4(x: Int, y: Int = 2*x) {} // error: not found value x
def g5(x: Int)(y: Int = 2*x) {} // OK
TwoParamClause involves two method invocations while the OneParamClause invokes the function method only once. I think the term you are looking for is currying. Among the many use cases, it helps you to breakdown the computation into small steps. This answer may convince you of usefulness of currying.
There is a difference between both versions concerning type inference. Consider
def f[A](a:A, aa:A) = null
f("x",1)
//Null = null
Here, the type A is bound to Any, which is a super type of String and Int. But:
def g[A](a:A)(aa:A) = null
g("x")(1)
error: type mismatch;
found : Int(1)
required: java.lang.String
g("x")(1)
^
As you see, the type checker only considers the first argument list, so A gets bound to String, so the Int value for aa in the second argument list is a type error.
Multiple parameter lists can help scala type inference for more details see: Making the most of Scala's (extremely limited) type inference
Type information does not flow from left to right within an argument list, only from left to right across argument lists. So, even though Scala knows the types of the first two arguments ... that information does not flow to our anonymous function.
...
Now that our binary function is in a separate argument list, any type information from the previous argument lists is used to fill in the types for our function ... therefore we don't need to annotate our lambda's parameters.
There are some cases where this distinction matters:
Multiple parameter lists allow you to have things like TwoParamClauses(2); which is automatically-generated function of type Int => Int which adds 2 to its argument. Of course you can define the same thing yourself using OneParamClause as well, but it will take more keystrokes
If you have a function with implicit parameters which also has explicit parameters, implicit parameters must be all in their own parameter clause (this may seem as an arbitrary restriction but is actually quite sensible)
Other than that, I think, the difference is stylistic.

Scala type parameter bracket

I know trait Foo[T] means T is a parametrized type.
But some times I can see trait Foo[T1,T2], or trait Foo[T1,T2,R], I cannot find anywhere describe the meaning of multiple types inside a type bracket, could you please point me the usages in this case? From what I speculate, Foo[T1,T2] just means, it defined two type parameters, it doesn't have to be take a T1 and return a T2.
When I read playframework documentation today, I again found myself confused about this question. In the documentation, it says:
A BodyParser[A] is basically an Iteratee[Array[Byte],A], meaning that
it receives chunks of bytes (as long as the web browser uploads some
data) and computes a value of type A as result.
This explanation sounds like, the second the type parameter inside a type bracket is a return type.
I also remember that trait Function2 [-T1, -T2, +R] extends AnyRef means a function that takes a T1 and T2, return a R.
Why do they put the return type in the bracket? Does it mean all the last parameter in a bracket is a return type? Or they just happened defined a new type R for the return type?
From what I speculate, Foo[T1,T2] just means, it defined two type parameters, it doesn't have to be take a T1 and return a T2.
A type parameter means nothing more than "I need any type but I'm not interested to know what it is for a concrete type", where 'I' is the programmer who writes the code. Type parameters can used like any other types such as Int, String or Complex - the only difference is that they are not known until one uses them.
See type Map[A, +B]. When you first read this, you can't know what the A and B are for, thus you have to read the documentation:
A map from keys of type A to values of type B.
It explains the types and their meaning. There is nothing more to know or understand. They are just two types. It is possible to call Map something like Map[Key, Value] but inside of source code it is better when type parameters have only one or two letters. This makes it easier to differ between the type parameters and concrete types.
It is the documentation which specifies what a type parameter means. And if there is no documentation you have to take a look to the sources and find their meaning by yourself. For example you have to do this with Function2 [-T1, -T2, +R]. The documentation tells us only this:
A function of 2 parameters.
Ok, we know that two of the three type parameters are parameters the function expects, but what is the third one? We take a look to the sources:
def apply(v1: T1, v2: T2): R
Ah, now we know that T1 and T2 are the parameters and that R is a return type.
Type parameters also can be found in method signatures like map:
class List[+A] {
..
def map[B](f: (A) โ‡’ B): List[B]
}
This is how map looks like when you use it with a List. A can be any type - it is the type of the elements a list contains. B is another arbitrary type. When you know what map does then you know what B does. Otherwise you have to understand map before. map expects a function which can transform each element of a List to another element. Because you know that A stands for the elements of the List you can derive from yourself that B have to be the type A is transformed to.
To answer all your other questions: This shouldn't be done in a single answer. There are a lot of other questions and answers on StackOverflow which can also answer your questions.
Summary
When you see some type parameters for example in Foo[T1, T2] you should not start to cry. Think: "Ok, I have a Foo which expects a T1 and a T2 and if I want to know what they do I have to read documentation or the sources."
Multiple types inside a type bracket means type parametrization on multiple types. Take for example
trait Pair[A, B]
This is a pair of values one having type A the other having type B.
Update:
I think you are interpreting too much into the semantics of type parameters. A type parametrized by multiple parameters is just that and nothing more. The position of a specific type parameter in the list of type parameters does not make it special in any way. Specifically the last parameter in a list of type parameters does not need to stand for 'the return type'.
The sentence from the play framework which you quoted explains the semantics of the type parameters for this one specific type. It does not generalize to other types. The same holds for the Function types: here the last type parameter happens to mean 'the return type'. This is not necessarily the case for other types though. The type Pair[A, B] from above is such an example. Here B is the type of the second component of the pair. There is no notion of a 'return type' here at all.
Type parameters of a parametrized type can appear anywhere inside the definition of the parametrized type where a 'regular' type could appear. That is, type parameters are just names for types which are bound to the actual types only when the parametrized type itself is instantiated.
Consider the following definition of a class Tuple:
class Tuple[A, B](a: A, b: B)
It is instantiated to a type of a tuple of Int and String like this:
type TupleIntString = Tuple[Int, String]
Which is essentially the same as
class TupleIntString(a: Int, b: String)
For an official source check the Scala Language Specification. Specifically Section 3.4 "Base Types and Member Definitions" under 1. the 4th bullet point says: "The base types of a parameterized type C[T_1, ..., T_n] are the base types of type C , where every occurrence of a type parameter a_i of C has been replaced by the corresponding parameter type T_i."
I think your question can actually be broken in three separate problems:
What's with the multiple type parameters for classes/traits/etc. ?
A classic example is a map from one type of object to another. If you want the type for the keys to be different from type of the value, but keep both generic, you need two type parameters. So, a Map[A,B] takes keys of generic type A and maps to values of generic type B. A user that wants a map from Bookmarks to Pages would declare it as Map[Bookmark, Page]. Having only one type parameters would not allow this distinction.
From what I speculate, Foo[T1,T2] just means, it defined two type parameters, it doesn't have to be take a T1 and return a T2.
No, all type parameters are equal citizens, though they have a meaning in that direction for function objects. See below.
What are all those +/-'s ?
They limit what the type parameters can bind to. The Scala by Example tutorial has a good explanation. See Section 8.2 Variance Annotations.
What is a function in scala?
Why do they put the return type in the bracket? Does it mean all the
last parameter in a bracket is a return type? Or they just happened
defined a new type R for the return type?
The Scala by Example tutorial explains this well in Section 8.6 Functions.
Their role is a bit similar to the ones (i.e. multiple type parameter) in a class, since traits are, after all, classes (without any constructor) meant to be added to some other class as a mixin.
The Scala spec gives the following example for Trait with multiple parameters:
Consider an abstract class Table that implements maps from a type of keys A to a type of values B.
The class has a method set to enter a new key/value pair into the table, and a method get that returns an optional value matching a given key.
Finally, there is a method apply which is like get, except that it returns a given default value if the table is unde๏ฌned for the given key. This class is implemented as follows.
abstract class Table[A, B](defaultValue: B) {
def get(key: A): Option[B]
def set(key: A, value: B)
def apply(key: A) = get(key) match {
case Some(value) => value
case None => defaultValue
}
}
Here is a concrete implementation of the Table class.
class ListTable[A, B](defaultValue: B) extends Table[A, B](defaultValue) {
private var elems: List[(A, B)]
def get(key: A) = elems.find(._1.==(key)).map(._2)
def set(key: A, value: B) = { elems = (key, value) :: elems }
}
Here is a trait that prevents concurrent access to the get and set operations of its
parent class
trait Synchronized Table[A, B] extends Table[A, B] {
abstract override def get(key: A): B =
synchronized { super.get(key) }
abstract override def set((key: A, value: B) =
synchronized { super.set(key, value) }
}
Note that SynchronizedTable does not pass an argument to its superclass, Table,
even though Table is de๏ฌned with a formal parameter.
Note also that the super calls in SynchronizedTableโ€™s get and set methods statically refer to abstract methods in class Table. This is legal, as long as the calling method is labeled abstract override (ยง5.2).
Finally, the following mixin composition creates a synchronized list table with
strings as keys and integers as values and with a default value 0:
object MyTable extends ListTable[String, Int](0) with SynchronizedTable
The object MyTable inherits its get and set method from SynchronizedTable.
The super calls in these methods are re-bound to refer to the corresponding implementations in ListTable, which is the actual supertype of SynchronizedTable in
MyTable.