Given the following:
scala> trait Foo { def get: String = "get" }
defined trait Foo
I implemented it and made an implicit:
scala> case class FooImpl(x: String) extends Foo {
| override def get = s"got $x"
| }
defined class FooImpl
scala> implicit val fooImpl = FooImpl("yo")
fooImpl: FooImpl = FooImpl(yo)
Lastly, I tried to write a method that implicitly resolves a Foo, returning get on that implicitly resolved class.
scala> def f[A: Foo](x: A) = x.get
<console>:11: error: Foo does not take type parameters
def f[A: Foo](x: A) = x.get
^
<console>:11: error: value get is not a member of type parameter A
def f[A: Foo](x: A) = x.get
^
But I got the above errors.
So I re-wrote it using the implicit keyword:
scala> def f(implicit x: Foo): String = x.get
f: (implicit x: Foo)String
scala> f
res0: String = got yo
Is it possible to re-write this example to not explicitly specify the implicit keyword?
Note - it's possible that I'm confusing this notation with TypeTag under the section, Using a Context bound of a Type Parameter.
You are using the wrong syntax, what you want is an upper bound:
scala> def f[A <: Foo](x: A) = x.get
f: [A <: Foo](x: A)String
Where you're saying that A is a subtype of Foo and that tells the compiler that A does have a method called get.
The syntax you're using (:) means that there's an implicit conversion from A to Foo[A], the problem is that Foo doesn't take a type parameter, you can also check it into the REPL where the column syntax is translated to an implicit parameter:
scala> trait Foo2[T]
defined trait Foo2
scala> def g[T: Foo2](x: Int): Int = x
g: [T](x: Int)(implicit evidence$1: Foo2[T])Int
Related
Ultimately what I want to do is provide one implementation of a type class for some specific type T and another implementation for all other types which are not T. I thought (perhaps incorrectly) that the easiest way to do this would be to try type negation via ambiguous implicits as described in this question. However, if I accidentally omit the implicit type class declaration, my code will still compile (should it?) but include bugs as only one of the implementations is used.
This is how the context bound is defined:
scala> trait NotAnInt[A]
defined trait NotAnInt
scala> implicit def everythingIsNotAnInt[A]: NotAnInt[A] = new NotAnInt[A] {}
everythingIsNotAnInt: [A]=> NotAnInt[A]
scala> implicit def intsAreInts1: NotAnInt[Int] = ???
intsAreInts1: NotAnInt[Int]
scala> implicit def intsAreInts2: NotAnInt[Int] = ???
intsAreInts2: NotAnInt[Int]
scala> implicit def nothingsAreInts1: NotAnInt[Nothing] = ???
nothingsAreInts1: NotAnInt[Nothing]
scala> implicit def nothingsAreInts2: NotAnInt[Nothing] = ???
nothingsAreInts2: NotAnInt[Nothing]
At this point NotAnInt[T] is summonable for all T except Int/Nothing:
scala> implicitly[NotAnInt[String]]
res3: NotAnInt[String] = $anon$1#1a24fe09
scala> implicitly[NotAnInt[Int]]
<console>:16: error: ambiguous implicit values:
both method intsAreInts1 of type => NotAnInt[Int]
and method intsAreInts2 of type => NotAnInt[Int]
match expected type NotAnInt[Int]
implicitly[NotAnInt[Int]]
^
scala> implicitly[NotAnInt[Nothing]]
<console>:18: error: ambiguous implicit values:
both method nothingsAreInts1 of type => NotAnInt[Nothing]
and method nothingsAreInts2 of type => NotAnInt[Nothing]
match expected type NotAnInt[Nothing]
implicitly[NotAnInt[Nothing]]
^
Now I have my NotAnInt context bound defined I can create my type class with its implementations:
scala> trait IntChecker[A] { def isInt(): Boolean }
defined trait IntChecker
scala> implicit val intIntChecker: IntChecker[Int] = new IntChecker[Int] { override def isInt = true }
intIntChecker: IntChecker[Int] = $anon$1#585dd35c
scala> implicit def otherIntChecker[A: NotAnInt]: IntChecker[A] = new IntChecker[A] { override def isInt = false }
otherIntChecker: [A](implicit evidence$1: NotAnInt[A])IntChecker[A]
This type class can be used as expected:
scala> def printIntStatus[T: IntChecker](t: T): Unit = { println(implicitly[IntChecker[T]].isInt()) }
printIntStatus: [T](t: T)(implicit evidence$1: IntChecker[T])Unit
scala> printIntStatus(3)
true
scala> printIntStatus("three")
false
However, the following also compiles:
scala> def printIntStatusWithBug[T](t: T): Unit = { println(implicitly[IntChecker[T]].isInt()) }
printIntStatusWithBug: [T](t: T)Unit
scala> printIntStatusWithBug(3)
false
scala> printIntStatusWithBug("three")
false
I would not expect this second function to compile as there should be no implicit IntChecker[T] available. I expect everythingIsNotAnInt is the cause of this problem but I can't think of a way around this.
I'm interested in why this approach fails as well as alternative methods on how to achieve the same thing. Thank you.
Consider the following alternative implementation (which uses Sabin's type inequalities)
trait =!=[A, B]
implicit def neq[A, B] : A =!= B = null
implicit def neqAmbig1[A] : A =!= A = null
implicit def neqAmbig2[A] : A =!= A = null
trait IntChecker[A] {
def isInt(): Boolean
}
object IntChecker {
import scala.reflect.ClassTag
implicit val intIntChecker: IntChecker[Int] = () => true
implicit def notIntIntChecker[T: ClassTag](implicit ev: T =!= Int): IntChecker[T] = () => false
}
def printIntStatus[T: IntChecker](t: T) = implicitly[IntChecker[T]].isInt()
import IntChecker._
printIntStatus(3)
printIntStatus("three")
which outputs
res0: Boolean = true
res1: Boolean = false
however the buggy implementation where we forget IntChecker bound
def printIntStatusWithBug[T](t: T) = implicitly[IntChecker[T]].isInt()
should not compile due to having T: ClassTag bound in
implicit def notIntIntChecker[T: ClassTag](implicit ev: T =!= Int)
giving compiler error
could not find implicit value for parameter e: IntChecker[T]
def printIntStatusWithBug[T](t: T) = implicitly[IntChecker[T]].isInt()
^
I'm using a class (that I cannot modify) containing a method which receives a value of type Any as parameter, like the following example:
class Foo(value: Int) {
def +(other: Any): Foo = ???
}
I would like to add a custom implementation for the method +() when it's used with a specific type. I would expect to be able to do something like:
implicit class RichFoo(foo: Foo) {
def +(other: Int): Foo = ???
}
// or
implicit class RichFoo(foo: Foo) {
def +[T <: Bar](other: T): T = ???
}
However, these approaches don't work.
Is it possible to do without extending the original class?
No.
To the compiler, implicit conversions and other rewrite rules (like those around Dynamic) are a "last resort" of sorts. They are only applied if code does not already typecheck as-is. When you do foo + x, the compiler already knows that + takes Any, so it doesn't even try to look for implicits. If you did foo - x, and Foo had no - of the correct type, only then would the compiler search for a conversion.
Instead, you can create a method with a new name, maybe add, that is not present in Foo but is present in RichFoo. This will not, however, protect you from doing foo + 1 instead of foo add 1, since both methods are valid.
implicit class RichFoo(foo: Foo) {
def add(other: Int): Foo = ???
}
You can use a phantom type to track what is convertible.
scala> trait Tagged[B]
defined trait Tagged
scala> type Of[+A, B] = A with Tagged[B]
defined type alias Of
scala> class Tagger[B] { def apply[A](a: A): A Of B = a.asInstanceOf[A Of B] }
defined class Tagger
scala> object tag { def apply[B]: Tagger[B] = new Tagger[B] }
defined object tag
The given thing:
scala> case class C(i: Int) { def +(x: Any): C = C(i + x.toString.toInt) }
defined class C
and a marker trait:
scala> trait CC
defined trait CC
Normally:
scala> C(42) + "17"
res0: C = C(59)
This works:
scala> val cc = tag[CC](C(42))
cc: Of[C,CC] = C(42)
But not this:
scala> val cc = tag[CC](C(42): Any)
java.lang.ClassCastException: C cannot be cast to Tagged
... 29 elided
Maybe this:
scala> val cc = tag[CC](C(42): Serializable)
cc: Of[Serializable,CC] = C(42)
Then:
scala> implicit class XC(v: Serializable Of CC) {
| def +(x: Any): C Of CC = tag[CC] {
| println("OK")
| v.asInstanceOf[C] + x
| }}
defined class XC
Abnormally:
scala> val valueAdded = cc + "17"
OK
valueAdded: Of[C,CC] = C(59)
There's surely a better way to do this:
scala> implicit def untagit(x: Serializable Of CC): C Of CC = tag[CC](x.asInstanceOf[C])
untagit: (x: Of[Serializable,CC])Of[C,CC]
scala> cc.i
res9: Int = 42
because that ruins it:
scala> val res: C = cc + "17"
<console>:18: error: type mismatch;
found : <refinement>.type (with underlying type Of[Serializable,CC])
required: ?{def +(x$1: ? >: String("17")): ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method XC of type (v: Of[Serializable,CC])XC
and method untagit of type (x: Of[Serializable,CC])Of[C,CC]
are possible conversion functions from <refinement>.type to ?{def +(x$1: ? >: String("17")): ?}
val res: C = cc + "17"
^
<console>:18: error: value + is not a member of Of[Serializable,CC]
val res: C = cc + "17"
^
Given:
scala> trait Resource[A] { def f: String }
defined trait Resource
scala> case class Foo(x: String)
defined class Foo
And then an implicit:
scala> implicit def fooToResource(foo: Foo): Resource[Foo] =
new Resource[Foo] { def f = foo.x }
The following works:
scala> implicitly[Resource[Foo]](Foo("foo")).f
res2: String = foo
I defined a function:
scala> def f[A](x: A)(implicit ev: Resource[A]): String = ev.f
f: [A](x: A)(implicit ev: Resource[A])String
However, the following code fails to compile:
scala> f(Foo("foo"))
<console>:17: error: could not find implicit value for parameter ev: Resource[Foo]
f(Foo("foo"))
Secondly, then I tried:
scala> f2(Foo("bippy"))
<console>:17: error: could not find implicit value for parameter ev: Resource[Foo]
f2(Foo("bippy"))
^
Lastly, I attempted:
scala> def g(foo: Foo)(implicit ev: Resource[Foo]): String = ev.f
g: (foo: Foo)(implicit ev: Resource[Foo])String
scala> g(Foo("5"))
<console>:17: error: could not find implicit value for parameter ev: Resource[Foo]
g(Foo("5"))
^
However, it failed too. How can I fix f?
Ok with Peter Neyens' answer, this is not a typeclass, this is an implicit conversion, which you should avoid - there should have been some warning, asking that you import scala.language.implicitConversions.
As a complement, here is why the first implicitly works:
Implicitly is just:
def implicitly[T](implicit ev: T): T = e
When you write implicitly[T] without supplying a parameter, it will look for an implicit of type T in scope and return it. However, you call implicitly with a parameter (I believe there is no legitimate reason to do that, ever), so it would just return your parameter, Foo("foo"), an instance of Foo. Except that you explicitly stated that T should be Resource[Foo]. If you had written a type ascription, such as (Foo("foo"): Resource[Foo]), it would have worked the same way. implicitly is not relevant here.
The point is that Foo("foo") is not of the expected type Resource[Foo], but just a Foo. The compiler would reject that, except that at this point, the implicit conversion you defined above kicks in, and your Foo instance is transformed into a Resource[Foo]. Then, you can call f.
Next, you call your f(Foo("foo")). There is an implicit parameter, however this time, you don't supply it. So the compiler looks for one (while it did no such thing the first time), and as there is no such instance, fails.
The implicit def fooToResource is not a type class instance, but does return one if you supply a Foo, that's the reason the following line works :
implicitly[Resource[Foo]](Foo("foo")).f
A solution would be to change the Resource.f function to take a parameter of type A :
trait Resource[A] {
def f(a: A): String
}
You then could define a Resource type class instance for Foo as follows:
case class Foo(x: String)
implicit val fooResource = new Resource[Foo] {
def f(foo: Foo) = foo.x
}
We can rewrite f to use the changed Resource :
def f[A](a: A)(implicit resA: Resource[A]): String = resA.f(a)
Which does what (I think) you need :
f(Foo("hello world")) // String = hello world
I am trying to understand the mechanism with which scala implements default type converions from sub to super type in scala.Predef. From the literature I gathered that this is done with the function
implicit def conforms[A] = new A<:<A { def apply(a:A)=a }
The parameterless function conforms[A] returns the implicit conversion A=>B as its only
function value (as a callable of type A=>A and thus of type A=>B, whenver A<:B).
However when the compiler looks for an implicit type conversion it needs an implicit value
of type A=>B not a function returning such a value. Thus my question:
When looking for a default type conversion from A=>B, where A<:B, how does the compiler
get from the function conforms[A] to its unique value.
The implicit resolution seeks for subtypes too, A <: B => A => A <: A => B, as in List[Int] <: Seq[Int].
scala> :paste
// Entering paste mode (ctrl-D to finish)
implicit val x: List[Int] = List(1, 2, 3)
def f(implicit x: Seq[Int]): Int = x.head
f
// Exiting paste mode, now interpreting.
x: Seq[Int] = List(1, 2, 3)
f: (implicit x: Seq[Int])Int
res1: Int = 1
So when making type conversion we look for A => B with A <: B, and A => A fits.
I'm not sure if I understood you right, but the defs are followed while searching for value of the needed type. It doesn't matter whether function takes zero, one, or more parameters. For example with zero:
implicit def implicitList[A]: List[A] = List() //the only obvious case
scala> implicitly[Seq[Int]]
// res0: Seq[Int] = List()
Or two:
case class Foo(str: String)
case class Bar(str: String)
case class Quux(str: String)
implicit val foo = Foo("foo")
implicit val bar = Bar("bar")
// how to build quux:
implicit def quux(implicit foo: Foo, bar: Bar): Quux = Quux(foo.str + bar.str)
implicitly[Quux]
// res2: Quux = Quux(foobar)
If we add any of:
implicit def quux2(implicit quux: Quux): Quux = quux
implicit def quux3(implicit foo: Foo): Quux = Quux(foo.str)
implicit val quux4: Quux = Quux("quux")
implicit def quux5[A]: Quux = Quux("poly")
We make implicit resolution undecidable for Quux:
scala> implicitly[Quux]
<console>:29: error: ambiguous implicit values:
both method quux of type (implicit foo: Foo, implicit bar: Bar)Quux
and method quux2 of type (implicit quux: Quux)Quux
match expected type Quux
implicitly[Quux]
^
I.e. there could be only one def or val in scope returning the type we are interested. And that is easy to verify statically.
But they will work if any of those is the only one in scope.
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.