Hi I have an implicit method like:
implicit def strToOpt(str: String): Option[String] = Option(str)
and it works for simple conversion, but when I type
implicitly[String]
I get
error: could not find implicit value for parameter e: String
Does REPL have some limitations in term of finding implicits?
I think you have misunderstood implicitly. It is defined as:
def implicitly[T](implicit e: T): T = e
Which roughly means, that implicitly[T] will return you an object of type T which is available in current scope (scope is not the precise word. Compiler looks at many places)
In your case doing implicitly[String] simply means that some object of type String is available.
For example this is valid:
scala> implicit val x = "Hey"
x: String = Hey
scala> implicitly[String]
res12: String = Hey
But what you rather need to do is:
scala> implicitly[(String) => Option[String]]
res10: String => Option[String] = <function1>
scala> res10("asd")
res11: Option[String] = Some(456)
PS: Note answer by #Ende Neu works as:
implicitly[Option[String]]("123")
Doing implicitly[Option[String]]("123"), in the implicitly function it takes T as argument which is String. But you have manually provided Option[String] as type parameter of method. So the compiler searches for a function again (by using implicitly again) that does String => Option[String] which it finds in your function.
Related
Having an implicit value and function defined as follows
implicit val v = 0
def function(implicit v: Int): Map[String, String] = Map("key" -> "value")
I can do
function.get("key") // res0: Option[String] = Some(value)
function(v)("key") // res0: String = value
but the following doesn't compile
function("key")
So how can I in one go access a map using parentheses and pass implicit parameter?
Here are your options:
scala> function.apply("key")
res6: String = value
scala> function(implicitly)("key")
res7: String = value
As compiler can't know if you want to pass an implicit parameter explicitly or call apply method, designers decided it will mean passing the implicit parameter.
You can either give up on using the syntactic sugar and just use apply that will resolve ambiguity or you can pass the parameter explicitly, but let the compiler find the value.
Here is my code snippet:
implicit def trick(s: String): String = s.toUpperCase
def fun(s: String)(implicit f: String => String): String = f(s)
println(s"String is ${fun("abc")}")
When I run it, it prints "abc" instead of "ABC". What am I doing wrong here?
PS
However, if I run the next code
implicit val n: Int = 100
def add(n1: Int)(implicit n2: Int) = n1 + n2
add(7)
all implicit magic works just fine.
Normally this would work. The compiler would implicitly convert the implicit method to a function through eta-expansion. Say, if I wanted to require an implicit Int => List[Int] for some reason.
implicit def trick(i: Int): List[Int] = List.fill(5)(i)
def fun(i: Int)(implicit f: Int => List[Int]): List[Int] = f(i)
scala> fun(4)
res5: List[Int] = List(4, 4, 4, 4, 4)
But your problem is that there is another implicit String => String already in scope that comes from Predef. Namely =:=[String, String], which extends String => String. Because this already exists in scope as a function, the compiler sees no need to look for anything else. And, if you convert your implicit method to an implicit function, you will get an ambiguous implicits error:
implicit val trick: String => String = _.toUpperCase
scala> fun("abc")
<console>:19: error: ambiguous implicit values:
both method $conforms in object Predef of type [A]=> <:<[A,A]
and value trick of type => String => String
match expected type String => String
fun("abc")
Really though, having an implicit String => String is probably not a good idea. Use a type class that wraps a function, instead.
case class Trick[A](f: A => A)
implicit val trick = Trick[String](_.toUpperCase)
def fun(s: String)(implicit t: Trick[String]): String = t.f(s)
scala> println(s"String is ${fun("abc")}")
String is ABC
Why does this code raise a type mismatch error in Scala 2.9.2? I expected that getOrElse returns type String but actually it returns java.io.Serializable:
scala> implicit def StringToOption(s:String) = Option(s)
StringToOption: (s: String)Option[String]
scala> "a".getOrElse("")
res0: String = a
scala> var opt:Option[String] = "a".getOrElse("")
<console>:8: error: type mismatch;
found : java.io.Serializable
required: Option[String]
var opt:Option[String] = "a".getOrElse("")
^
This is OK:
scala> implicit def StringToOption(s:String): Option[String] = Option(s)
StringToOption: (s: String)Option[String]
scala> var b:Option[String] = "a".getOrElse("") toString
b: Option[String] = Some(a)
It's an unwanted case of incomplete tree traversal. The signature of getOrElse allows type widening, so when it realizes that String is not Option[String] it first tries to fill in a different type ascription on getOrElse, i.e. Serializable. But now it has "a".getOrElse[Serializable]("") and it's stuck--it doesn't realize, I guess, that the problem was making the type too general before checking for implicits.
Once you realize the problem, there's a fix:
"a".getOrElse[String]("")
Now the typer doesn't wander down the let's-widen path, and finds the implicit.
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.
Does anyone know if something like this is possible in Scala:
case class Thing(property:String)
def f(thing:Thing, prop:String = thing.property) = println(prop)
The above code doesn't compile; giving the error error: not found: value thing at thing.property
The following shows the expected behaviour:
f(Thing("abc"), "123") // prints "123"
f(Thing("abc")) // prints "abc"
I realise I could make the prop argument an Option[String] and do the check in the function definition, but I was wondering if there was a way around it with the new named/default argument support in 2.8.0.
Yes, it's possible in Scala 2.8. Here's a quote from the "Named and Default Arguments in Scala 2.8" design document:
Since the scope of a parameter extends
over all subsequent parameter lists
(and the method body), default
expressions can depend on parameters
of preceding parameter lists (but not
on other parameters in the same
parameter list). Note that when using
a default value which depends on
earlier parameters, the actual
arguments are used, not the default
arguments.
def f(a: Int = 0)(b: Int = a + 1) = b // OK
And another example:
def f[T](a: Int = 1)(b: T = a + 1)(c: T = b)
// generates:
// def f$default$1[T]: Int = 1
// def f$default$2[T](a: Int): Int = a + 1
// def f$default$3[T](a: Int)(b: T): T = b
According to this, your code may look as follows:
scala> case class Thing(property:String)
defined class Thing
scala> def f(thing:Thing)(prop:String = thing.property) = println(prop)
f: (thing: Thing)(prop: String)Unit
scala> f(Thing("abc"))("123")
123
scala> f(Thing("abc"))()
abc
Another simple solution is just to overload the method:
case class Thing (property: String)
def f(thing: Thing, prop: String) = println(prop)
def f(thing: Thing) = f(thing, thing.property)
This is exactly what Option is for. You can use the getOrElse method before the method call or inside the method f.
scala> val abc = Some("abc")
abc: Some[java.lang.String] = Some(abc)
scala> val none: Option[String] = None
none: Option[String] = None
scala> println(abc getOrElse "123")
abc
scala> println(none getOrElse "123")
123
scala> def f(o: Option[String]) = println(o getOrElse "123")
f: (o: Option[String])Unit
scala> f(abc)
abc
scala> f(none)
123
Oh here is something you could do via default arguments:
scala> case class Thing(property: String = "123")
defined class Thing
scala> def f(t: Thing) = println(t.property)
f: (t: Thing)Unit
scala> f(Thing("abc"))
abc
scala> f(Thing())
123
The expected behaviour can be achieved with simple overloading. I needed to put the method in an object because it looks like the REPL does not allow direct overloaded function declarations:
scala> object O {
def overloaded(t:Thing) = println(t.property)
def overloaded(t:Thing,s:String) = println(s)
}
defined module O
scala> O.overloaded(Thing("abc"), "123")
123
scala> O.overloaded(Thing("abc"))
abc