Make constructor params implicitly available in class body - scala

I would like to make the explicit constructor parameters of my class implicitly available in the class body.
I can mark the second and subsequent parameters as "implicit val", which works:
scala> class Foo(x: Int, implicit val y: String) {
| println(implicitly[String])
| }
defined class Foo
scala> new Foo(1,"hello")
hello
but if I mark the first parameter as implicit, then Scala thinks I am marking the whole argument list as an implicit argument list, and adds an empty first argument list:
scala> class Bar(implicit val x: Int, y: String) {
| println(implicitly[Int])
| }
defined class Bar
scala> new Bar(1,"hello")
<console>:9: error: too many arguments for constructor Bar: ()(implicit x: Int, implicit y: String)Bar
new Bar(1,"hello")
^
Is there any way to make the first explicit constructor argument explicitly in scope?

You can make it implicitly available by using an implicit def inside:
class Foo(val x: Int, implicit val y: String) {
implicit def ix = x
}
which is hideously verbose, but it doesn't look like there is another way to get around the ambiguity between implicit marking a parameter list implicit and implicit val marking an implicit field.

I would have said, Add other local modifiers:
scala> class Foo(#deprecated("","") private implicit val x: Int, val y: String) { println(implicitly[Int]) }
warning: there were 1 deprecation warning(s); re-run with -deprecation for details
defined class Foo
scala> new Foo(42, "hi")
<console>:9: error: too many arguments for constructor Foo: ()(implicit x: Int, y: String)Foo
new Foo(42, "hi")
^
Syntactically, that's different from the leading implicit keyword, so maybe it's a parser bug, or maybe it does distinguish an implicit param list from a leading param marked locally-implicit but doesn't use the difference.

class Foo(x: Int, y: String) {
implicit val xImp = x
println(implicitly[Int])
}
Actually I would do it similarly for the first case too. This is a situation where I think that the lot more understandable code is worth a bit more verbosity:
class Foo(x: Int, y: String) {
implicit val yImp = y
println(implicitly[String])
}

Related

Scala: implicitly to implicit class

Given:
implicit class Foo(val i: Int) {
def addValue(v: Int): Int = i + v
}
is it possible apply to it any implicitly?
I get an error here:
<console>:14: error: could not find implicit value for parameter e: Foo
implicitly[Foo]
An implicit class Foo(val i: Int) means that there is an implicit conversion from Int to Foo. So implicitly[Int => Foo] should work.
Think about it like this: if you could summon a Foo with implicitly[Foo], which Foo would you expect to get? A Foo(0)? A Foo(1)? A Foo(2)?
For further details,
implcitly key word can be explained as following
implitly[T] means return implicit value of type T in the context
Which means, to get Foo implicitly you need to create an implicit value in the scope
For example,
implicit class Foo(val i: Int) {
def addValue(v: Int): Int = i + v
}
implicit val foo:Foo = Foo(1)
val fooImplicitly = implicitly[Foo] // Foo(1)
Also, note that Foo itself is only a class,
But by putting implicit key word in front of class definition,
Compiler creates an implicit function of type Int => Foo

Invoking Function with Implicit and Non-implicit

I'm trying to define, what I think to be a "default argument", with an implicit argument:
scala> def f(implicit x: Int, y: String) = y
f: (implicit x: Int, implicit y: String)String
Note - I tried to define implicit x: Int as the second argument, but I got a compile-time error:
scala> def f(y: String, implicit x: Int) = y
<console>:1: error: identifier expected but 'implicit' found.
def f(y: String, implicit x: Int) = y
Anyway, I define an implicit Int.
scala> implicit val x: Int = 100
x: Int = 100
Then I failed to invoke f with just a String argument:
scala> f("foo")
<console>:10: error: not enough arguments for method f:
(implicit x: Int, implicit y: String)String.
Unspecified value parameter y.
f("foo")
^
Next, I tried to invoke the f function by specifying the argument. That failed too.
scala> f(y = "foo")
<console>:10: error: not enough arguments for method f:
(implicit x: Int, implicit y: String)String.
Unspecified value parameter x.
f(y = "foo")
^
Is it possible to invoke the function f by providing an implicit and providing only a single argument for y?
Implicit parameter sections are all or nothing—either you explicitly pass every argument (assuming they don't have default values) or none of them. You need to do something like this if you want f("foo") to work:
def f(y: String)(implicit x: Int) = y
I'd be careful about this approach, though—I'm personally increasingly inclined to think that using implicits for anything except type class instances is a bad idea, and having an implicit Int value floating around is kind of scary.

Class constructor declaration... Two ways of declaring the same thing?

I would like an explanation of difference for example between this declaration:
class Clazz(param1: String, param2: Integer)
and this one:
class Clazz(param1: String)(param2: Integer)
Does second declaration affect just the way of instantiating the objects or is there any deeper reason I don't know about.
One reason I thought about would be multiple variable length of parameters for example:
class Clazz(param1: String*)(param2: Integer*)
So are there any others?
#1 Type inference. It goes from left to right and is done per parameter list.
scala> class Foo[A](x: A, y: A => Unit)
defined class Foo
scala> new Foo(2, x => println(x))
<console>:24: error: missing parameter type
new Foo(2, x => println(x))
^
scala> class Foo[A](x: A)(y: A => Unit)
defined class Foo
scala> new Foo(2)(x => println(x))
res22: Foo[Int] = Foo#4dc1e4
#2 Implicit parameter list.
scala> class Foo[A](x: A)(implicit ord: scala.Ordering[A]) {
| def compare(y: A) = ord.compare(x, y)
| }
defined class Foo
scala> new Foo(3)
res23: Foo[Int] = Foo#965701
scala> res23 compare 7
res24: Int = -1
scala> new Foo(new {})
<console>:24: error: No implicit Ordering defined for java.lang.Object.
new Foo(new {})
^
In the second version you are declaring a curried primary constructor for Clazz. So the difference between the two versions is the same as difference between "normal" and curried functions in Scala, i.e.
def foo(param1: String, param2: Int)
def foo(param1: String)(param2: Int)
Most of the time both declarations can be used interchangeably but if you often need to curry function then it makes more sense to declare it in curried form. Note you can also convert a normal function or even constructor into a curried form, for e.g you could transform your normal Clazz constructor into curried form using this:
(new Clazz(_, _)).curried
You also need multiple parameter lists if you are passing an implicit value (as the keyword implicit applies to the complete parameter list)

What is the Scala identifier "implicitly"?

I have seen a function named implicitly used in Scala examples. What is it, and how is it used?
Example here:
scala> sealed trait Foo[T] { def apply(list : List[T]) : Unit }; object Foo {
| implicit def stringImpl = new Foo[String] {
| def apply(list : List[String]) = println("String")
| }
| implicit def intImpl = new Foo[Int] {
| def apply(list : List[Int]) = println("Int")
| }
| } ; def foo[A : Foo](x : List[A]) = implicitly[Foo[A]].apply(x)
defined trait Foo
defined module Foo
foo: [A](x: List[A])(implicit evidence$1: Foo[A])Unit
scala> foo(1)
<console>:8: error: type mismatch;
found : Int(1)
required: List[?]
foo(1)
^
scala> foo(List(1,2,3))
Int
scala> foo(List("a","b","c"))
String
scala> foo(List(1.0))
<console>:8: error: could not find implicit value for evidence parameter of type
Foo[Double]
foo(List(1.0))
^
Note that we have to write implicitly[Foo[A]].apply(x) since the compiler thinks that implicitly[Foo[A]](x) means that we call implicitly with parameters.
Also see How to investigate objects/types/etc. from Scala REPL? and Where does Scala look for implicits?
implicitly is avaliable in Scala 2.8 and is defined in Predef as:
def implicitly[T](implicit e: T): T = e
It is commonly used to check if an implicit value of type T is available and return it if such is the case.
Simple example from retronym's presentation:
scala> implicit val a = "test" // define an implicit value of type String
a: java.lang.String = test
scala> val b = implicitly[String] // search for an implicit value of type String and assign it to b
b: String = test
scala> val c = implicitly[Int] // search for an implicit value of type Int and assign it to c
<console>:6: error: could not find implicit value for parameter e: Int
val c = implicitly[Int]
^
Here are a few reasons to use the delightfully simple method implicitly.
To understand/troubleshoot Implicit Views
An Implicit View can be triggered when the prefix of a selection (consider for example, the.prefix.selection(args) does not contain a member selection that is applicable to args (even after trying to convert args with Implicit Views). In this case, the compiler looks for implicit members, locally defined in the current or enclosing scopes, inherited, or imported, that are either Functions from the type of that the.prefix to a type with selection defined, or equivalent implicit methods.
scala> 1.min(2) // Int doesn't have min defined, where did that come from?
res21: Int = 1
scala> implicitly[Int => { def min(i: Int): Any }]
res22: (Int) => AnyRef{def min(i: Int): Any} = <function1>
scala> res22(1) //
res23: AnyRef{def min(i: Int): Int} = 1
scala> .getClass
res24: java.lang.Class[_] = class scala.runtime.RichInt
Implicit Views can also be triggered when an expression does not conform to the Expected Type, as below:
scala> 1: scala.runtime.RichInt
res25: scala.runtime.RichInt = 1
Here the compiler looks for this function:
scala> implicitly[Int => scala.runtime.RichInt]
res26: (Int) => scala.runtime.RichInt = <function1>
Accessing an Implicit Parameter Introduced by a Context Bound
Implicit parameters are arguably a more important feature of Scala than Implicit Views. They support the type class pattern. The standard library uses this in a few places -- see scala.Ordering and how it is used in SeqLike#sorted. Implicit Parameters are also used to pass Array manifests, and CanBuildFrom instances.
Scala 2.8 allows a shorthand syntax for implicit parameters, called Context Bounds. Briefly, a method with a type parameter A that requires an implicit parameter of type M[A]:
def foo[A](implicit ma: M[A])
can be rewritten as:
def foo[A: M]
But what's the point of passing the implicit parameter but not naming it? How can this be useful when implementing the method foo?
Often, the implicit parameter need not be referred to directly, it will be tunneled through as an implicit argument to another method that is called. If it is needed, you can still retain the terse method signature with the Context Bound, and call implicitly to materialize the value:
def foo[A: M] = {
val ma = implicitly[M[A]]
}
Passing a subset of implicit parameters explicitly
Suppose you are calling a method that pretty prints a person, using a type class based approach:
trait Show[T] { def show(t: T): String }
object Show {
implicit def IntShow: Show[Int] = new Show[Int] { def show(i: Int) = i.toString }
implicit def StringShow: Show[String] = new Show[String] { def show(s: String) = s }
def ShoutyStringShow: Show[String] = new Show[String] { def show(s: String) = s.toUpperCase }
}
case class Person(name: String, age: Int)
object Person {
implicit def PersonShow(implicit si: Show[Int], ss: Show[String]): Show[Person] = new Show[Person] {
def show(p: Person) = "Person(name=" + ss.show(p.name) + ", age=" + si.show(p.age) + ")"
}
}
val p = Person("bob", 25)
implicitly[Show[Person]].show(p)
What if we want to change the way that the name is output? We can explicitly call PersonShow, explicitly pass an alternative Show[String], but we want the compiler to pass the Show[Int].
Person.PersonShow(si = implicitly, ss = Show.ShoutyStringShow).show(p)
Starting Scala 3 implicitly has been replaced with improved summon which has the advantage of being able to return a more precise type than asked for
The summon method corresponds to implicitly in Scala 2. It is
precisely the same as the the method in Shapeless. The difference
between summon (or the) and implicitly is that summon can return a
more precise type than the type that was asked for.
For example given the following type
trait F[In]:
type Out
def f(v: Int): Out
given F[Int] with
type Out = String
def f(v: Int): String = v.toString
implicitly method would summon a term with erased type member Out
scala> implicitly[F[Int]]
val res5: F[Int] = given_F_Int$#7d0e5fbb
scala> implicitly[res5.Out =:= String]
1 |implicitly[res5.Out =:= String]
| ^
| Cannot prove that res5.Out =:= String.
scala> val x: res5.Out = ""
1 |val x: res5.Out = ""
| ^^
| Found: ("" : String)
| Required: res5.Out
In order to recover the type member we would have to refer to it explicitly which defeats the purpose of having the type member instead of type parameter
scala> implicitly[F[Int] { type Out = String }]
val res6: F[Int]{Out = String} = given_F_Int$#7d0e5fbb
scala> implicitly[res6.Out =:= String]
val res7: res6.Out =:= String = generalized constraint
However summon defined as
def summon[T](using inline x: T): x.type = x
does not suffer from this problem
scala> summon[F[Int]]
val res8: given_F_Int.type = given_F_Int$#7d0e5fbb
scala> summon[res8.Out =:= String]
val res9: String =:= String = generalized constraint
scala> val x: res8.Out = ""
val x: res8.Out = ""
where we see type member type Out = String did not get erased even though we only asked for F[Int] and not F[Int] { type Out = String }. This can prove particularly relevant when chaining dependently typed functions:
The type summoned by implicitly has no Out type member. For this
reason, we should avoid implicitly when working with dependently typed
functions.
A "teach you to fish" answer is to use the alphabetic member index currently available in the Scaladoc nightlies. The letters (and the #, for non-alphabetic names) at the top of the package / class pane are links to the index for member names beginning with that letter (across all classes). If you choose I, e.g., you'll find the implicitly entry with one occurrence, in Predef, which you can visit from the link there.

Overload constructor for Scala's Case Classes?

In Scala 2.8 is there a way to overload constructors of a case class?
If yes, please put a snippet to explain, if not, please explain why?
Overloading constructors isn't special for case classes:
case class Foo(bar: Int, baz: Int) {
def this(bar: Int) = this(bar, 0)
}
new Foo(1, 2)
new Foo(1)
However, you may like to also overload the apply method in the companion object, which is called when you omit new.
object Foo {
def apply(bar: Int) = new Foo(bar)
}
Foo(1, 2)
Foo(1)
In Scala 2.8, named and default parameters can often be used instead of overloading.
case class Baz(bar: Int, baz: Int = 0)
new Baz(1)
Baz(1)
You can define an overloaded constructor the usual way, but to invoke it you have to use the "new" keyword.
scala> case class A(i: Int) { def this(s: String) = this(s.toInt) }
defined class A
scala> A(1)
res0: A = A(1)
scala> A("2")
<console>:8: error: type mismatch;
found : java.lang.String("2")
required: Int
A("2")
^
scala> new A("2")
res2: A = A(2)