I want to define a compression method that compresses a collection of a certain type Int or String into a string. I wanted to combine the two methods that I currently have:
def compressString[T <: IndexedSeq[String]]: (T) =>
String = (array: T) => array.mkString(" ")
def compressInt[T <: IndexedSeq[Int]]: (T) =>
String = (array: T) => array.mkString(" ")
Into one method. I tried to do higher kinded type with T[Int] but it didn't work that way. I also tried to do:
def compress[U, T <: IndexedSeq[U]]: (T) => String =
(array: T) => array.mkString(" ")
However, the compiler gives me this error:
[error] type mismatch;
[error] found : Iterator[Int(in method compress)]
[error] required: Iterator[scala.Int]
[error] collect(array.iterator, Vector.empty[String], 0).mkString("\t")
[error] ^
[error] SVM.scala:55: type mismatch;
[error] found : java.lang.String
[error] required: String(in method compress)
[error] override def compress[String, T <: IndexedSeq[String]]: (T) => String = (array: T) => array.mkString("\t")
In general, I want to eventually override this method and provide concrete implementation (the method that deals with Int is different from String). How do I combine these two methods??
In order to make your generic method compile, you need to pass the first type argument as the type of IndexedSeq, i.e.
def compress[U, T <: IndexedSeq[U]]: (T) => String = {
(array: T) => array.mkString(" ")
}
then you can invoke it like,
val strings = compress[String,Vector[String]](Vector("a","b")) // strings: String = a b
val ints = compress[Int,Vector[Int]](Vector(1,2)) // ints: String = 1 2
However, I think a type class would fit much better in the case that you want to have ad hoc polymorphism.
For example, you can define the following type class:
#implicitNotFound("No compressor found for type ${T}")
trait Compressor[T] {
def compress(array: IndexedSeq[T]): String
}
and create an implementation for every type that you want to support compression
implicit val stringCompressor = new Compressor[String] {
override def compress(array: IndexedSeq[String]): String = array.mkString(" ")
}
implicit val intCompressor = new Compressor[Int] {
override def compress(array: IndexedSeq[Int]): String = array.mkString(" ")
}
then you can call the methods directly
val strings = stringCompressor.compress(Vector("a","b")) // strings: String = a b
val ints = intCompressor.compress(Vector(1,2)) // ints: String = 1 2
or you can define a generic method that takes an implicit parameter
def compress[T](array: IndexedSeq[T])(implicit compressor: Compressor[T]): String = {
compressor.compress(array)
}
// or equivalently
def compress[T: Compressor](array: IndexedSeq[T]): String = {
implicitly[Compressor[T]].compress(array)
}
and use like this
val strings = compress(Vector("a","b")) // strings: String = a b
val ints = compress(Vector(1,2)) // ints: String = 1 2
if there is no implicit compressor defined in the scope, the compiler will give you an error, e.g.
compress(Vector(true, false))
error: No compressor found for type Boolean
compress(Vector(true, false))
^
Hope it helps.
Related
For example I have a class Value and a implicit function convert string to Value:
case class Value(v: String)
implicit def strToValue(s: String): Value = Value(s)
And here is a trait which has a method returns Value:
trait ReturnValue {
def f: Value
}
Because the implicit conversion exists, I can implement method f by just return a String literal:
object Obj1 extends ReturnValue {
override def f: Value = "123"
}
And of course return a variable of type String just works fine:
object Obj2 extends ReturnValue {
override def f: Value = {
val v = Some("123").getOrElse("234")
v
}
}
But when I trying to use the result of Option.getOrElse directly as the return value:
object Obj3 extends ReturnValue {
override def f: Value = Some("123").getOrElse("234") // Compilation error: type mismatch
}
A compilation error occurred:
Error:(23, 50) type mismatch;
found : java.io.Serializable
required: Entry.Value
override def f: Value = Some("123").getOrElse("234") // Compilation error: type mismatch
It seems that type inference here is failed. Type String is not inferred, and then the implicit conversion cannot be matched. (Full file is here)
I have tried other functions which have type parameter, such as "map", they all works perfectly.
Why is the Option.getOrElse so special that type inference failed here?
This variants leads to the same compile error, and probably shows how compiler deconstructs the expression:
object Obj3 extends ReturnValue {
override def f: Value = {
val v = Some("123") // is of type Some(String)
v.getOrElse("234": Value) // Compilation error: type mismatch
}
}
Same error can also be achieved without any traits, with following simple repro:
case class Value(v: String)
implicit def strToValue(s: String): Value = Value(s)
val vs = Some("123")
val v: Value = vs.getOrElse("234")
It seems the compiler applies the conversion to Value on the argument of getOrElse, instead of on its result. The fact is does can be confirmed with output with enabled scalacOptions in Compile ++= Seq("-Xprint-types", "-Xprint:typer") (cleaned a bit - deleted obviously unrelated annotations):
private[this] val v: Value =
vs.getOrElse{[B >: String](default: => B)B}[java.io.Serializable]{(default: => java.io.Serializable)java.io.Serializable}( strToValue{(s: String)Value}("234"{String("234")}){Value} ){
I think the inference works as follows:
vs type is known as Some[String]
getOrElse declaration is def getOrElse[B >: A](default: => B): B (A is String here)
compilers infers the B as Value, as this is the expected result type of the expression.
the most specific supertype of Value and String is Serializable
You can also note how it behaves when you remove the implicit conversion completely. The error for val v: Value = vs.getOrElse("234") is then: type mismatch;
found : String("234")
required: Value
This appears to be a compiler bug. Here's an example showing the odd behavior.
case class ValString(string: String)
object ValString {
implicit def string2ValString(string: String): ValString = ValString(string)
}
case class ValThing( one: ValString, two: ValString, three: ValString, four: ValString, five: ValString)
val opt = Option("aString")
val x = ValThing(
if(opt.isEmpty) "" else opt.get,
opt.fold("")(identity),
opt.orElse(Option("")).get,
opt.getOrElse(""): String,
ValString(opt.getOrElse(""))
)
The above all works, however
val x = ValThing( opt.getOrElse(""), .... )
fails because it interprets the output of the getOrElse as a Serializable
I've got a trait implementing an Ordered trait of Scala:
package stackQuestions
trait ValueTrait[TYPE] extends Ordered[ValueTrait[TYPE]]{
def value: Double
}
and a subclass:
package stackQuestions
class Value[A](list: List[A], function: (A, A) => Double) extends ValueTrait[A] {
private val _value: Double = list.zip(list.tail).map(pair => function(pair._1, pair._2)).sum
override def value: Double = _value
override def compare(that: ValueTrait[A]): Int = {
(this.value - that.value).signum
}
}
Basically, when an object of Value is created with provided function, the value is calculated. What I want to achieve is to sort a collection of Value objects based on their value. This should be guaranteed by Ordered trait. I've written some simple tests for this:
package stackQuestions
import org.scalatest.FunSpec
class ValueTest extends FunSpec {
def evaluationFunction(arg1: Int, arg2: Int): Double = {
if (arg1 == 1 && arg2 == 2) return 1.0
if (arg1 == 2 && arg2 == 1) return 10.0
0.0
}
val lesserValue = new Value(List(1, 2), evaluationFunction) // value will be: 1.0
val biggerValue = new Value(List(2, 1), evaluationFunction) // value will be: 10.0
describe("When to Value objects are compared") {
it("should compare by calculated value") {
assert(lesserValue < biggerValue)
}
}
describe("When to Value objects are stored in collection") {
it("should be able to get max value, min value, and get sorted") {
val collection = List(biggerValue, lesserValue)
assertResult(expected = lesserValue)(actual = collection.min)
assertResult(expected = biggerValue)(actual = collection.max)
assertResult(expected = List(lesserValue, biggerValue))(actual = collection.sorted)
}
}
}
However, when sbt test -Xlog-implicits I've get error messages:
[info] Compiling 1 Scala source to /project/target/scala-2.11/test-classes ...
[error] /project/src/test/scala/stackQuestions/ValueTest.scala:24:64: diverging implicit expansion for type Ordering[stackQuestions.Value[Int]]
[error] starting with method $conforms in object Predef
[error] assertResult(expected = lesserValue)(actual = collection.min)
[error] ^
[error] /project/src/test/scala/stackQuestions/ValueTest.scala:25:64: diverging implicit expansion for type Ordering[stackQuestions.Value[Int]]
[error] starting with method $conforms in object Predef
[error] assertResult(expected = biggerValue)(actual = collection.max)
[error] ^
[error] /project/src/test/scala/stackQuestions/ValueTest.scala:27:83: diverging implicit expansion for type scala.math.Ordering[stackQuestions.Value[Int]]
[error] starting with method $conforms in object Predef
[error] assertResult(expected = List(lesserValue, biggerValue))(actual = collection.sorted)
[error] ^
[error] three errors found
[error] (Test / compileIncremental) Compilation failed
[error] Total time: 1 s, completed 2018-09-01 08:36:18
I've dug for similar problems and after reading:
What's a “diverging implicit expansion” scalac message mean?,
Why am I getting a “ diverging implicit expansion” error when trying to sort instances of an ordered class?,
How can I solve the Diverging implicit expansion for type,
scala - Confusing “diverging implicit expansion” error when using “sortBy”,
I get to know that the compiler is confused about how to choose the proper function for comparison. I know that I can circumvent this using sortBy(obj => obj.fitness) but is there any way to use less verbose sorted method?
Scala uses Ordering[T] trait for methods sorted, min and max of a collection of type T. It can generate instances of Ordering[T] automatically for T's that extend Ordered[T].
Because of Java compatibility Ordering[T] extends java.util.Comparator[T], which is invariant in T, so Ordering[T] has to be invariant in T as well. See this issue: SI-7179.
This means that Scala can't generate instances of Ordering[T] for T's that are subclasses of classes that implement Ordered.
In your code you have val collection = List(biggerValue, lesserValue), which has type List[Value[Int]]. Value doesn't have its own Ordered or Ordering, so Scala can't sort this collection.
To fix you can specify collection to have type List[ValueTrait[Int]]:
val collection = List[ValueTrait[Int]](biggerValue, lesserValue)
Or define an explicit Ordering for Value[T]:
object Value {
implicit def ord[T]: Ordering[Value[T]] =
Ordering.by(t => t: ValueTrait[T])
}
You can also consider using a different design in this problem, if it suits your other requirements:
In your code all instances of ValueTrait[TYPE] have a value of type Double, and the distinctions in subclass and TYPE don't seem to be important at runtime. So you can just define a case class Value(value: Double) and have different factory methods to create Value's from different kinds of arguments.
case class Value(value: Double) extends Ordered[Value] {
override def compare(that: Value): Int = this.value compareTo that.value
}
object Value {
def fromList[A](list: List[A], function: (A, A) => Double): Value =
Value((list, list.tail).zipped.map(function).sum)
}
And the usage:
scala> val lesserValue = Value.fromList(List(1, 2), evaluationFunction)
lesserValue: Value = Value(1.0)
scala> val biggerValue = Value.fromList(List(2, 1), evaluationFunction)
biggerValue: Value = Value(10.0)
scala> val collection = List(biggerValue, lesserValue)
collection: List[Value] = List(Value(10.0), Value(1.0))
scala> (collection.min, collection.max, collection.sorted)
res1: (Value, Value, List[Value]) = (Value(1.0),Value(10.0),List(Value(1.0), Value(10.0)))
For example I have a class Value and a implicit function convert string to Value:
case class Value(v: String)
implicit def strToValue(s: String): Value = Value(s)
And here is a trait which has a method returns Value:
trait ReturnValue {
def f: Value
}
Because the implicit conversion exists, I can implement method f by just return a String literal:
object Obj1 extends ReturnValue {
override def f: Value = "123"
}
And of course return a variable of type String just works fine:
object Obj2 extends ReturnValue {
override def f: Value = {
val v = Some("123").getOrElse("234")
v
}
}
But when I trying to use the result of Option.getOrElse directly as the return value:
object Obj3 extends ReturnValue {
override def f: Value = Some("123").getOrElse("234") // Compilation error: type mismatch
}
A compilation error occurred:
Error:(23, 50) type mismatch;
found : java.io.Serializable
required: Entry.Value
override def f: Value = Some("123").getOrElse("234") // Compilation error: type mismatch
It seems that type inference here is failed. Type String is not inferred, and then the implicit conversion cannot be matched. (Full file is here)
I have tried other functions which have type parameter, such as "map", they all works perfectly.
Why is the Option.getOrElse so special that type inference failed here?
This variants leads to the same compile error, and probably shows how compiler deconstructs the expression:
object Obj3 extends ReturnValue {
override def f: Value = {
val v = Some("123") // is of type Some(String)
v.getOrElse("234": Value) // Compilation error: type mismatch
}
}
Same error can also be achieved without any traits, with following simple repro:
case class Value(v: String)
implicit def strToValue(s: String): Value = Value(s)
val vs = Some("123")
val v: Value = vs.getOrElse("234")
It seems the compiler applies the conversion to Value on the argument of getOrElse, instead of on its result. The fact is does can be confirmed with output with enabled scalacOptions in Compile ++= Seq("-Xprint-types", "-Xprint:typer") (cleaned a bit - deleted obviously unrelated annotations):
private[this] val v: Value =
vs.getOrElse{[B >: String](default: => B)B}[java.io.Serializable]{(default: => java.io.Serializable)java.io.Serializable}( strToValue{(s: String)Value}("234"{String("234")}){Value} ){
I think the inference works as follows:
vs type is known as Some[String]
getOrElse declaration is def getOrElse[B >: A](default: => B): B (A is String here)
compilers infers the B as Value, as this is the expected result type of the expression.
the most specific supertype of Value and String is Serializable
You can also note how it behaves when you remove the implicit conversion completely. The error for val v: Value = vs.getOrElse("234") is then: type mismatch;
found : String("234")
required: Value
This appears to be a compiler bug. Here's an example showing the odd behavior.
case class ValString(string: String)
object ValString {
implicit def string2ValString(string: String): ValString = ValString(string)
}
case class ValThing( one: ValString, two: ValString, three: ValString, four: ValString, five: ValString)
val opt = Option("aString")
val x = ValThing(
if(opt.isEmpty) "" else opt.get,
opt.fold("")(identity),
opt.orElse(Option("")).get,
opt.getOrElse(""): String,
ValString(opt.getOrElse(""))
)
The above all works, however
val x = ValThing( opt.getOrElse(""), .... )
fails because it interprets the output of the getOrElse as a Serializable
I'm trying to play with HList's from Shapeless.
This is my first try:
trait Column[T] {
val name: String
}
case class CV[T](col: Column[T], value: T)
object CV {
object columnCombinator extends Poly2 {
implicit def algo[A] = at[(String, String, String), CV[A]] { case ((suffix, separator, sql), cv) ⇒
(suffix, separator, if (sql == "") cv.col.name+suffix else sql+separator+cv.col.name+suffix)
}
}
def combine[A <: HList](columns: A, suffix: String, separator: String = " and ")
(implicit l: LeftFolder[A, (String, String, String), columnCombinator.type]): String =
columns.foldLeft((suffix, separator, ""))(columnCombinator)._3
}
The problem is I don't know what foldLeft does return in this example.
I expect it to return (String, String, String), but the compiler tells me that returns l.Out. What is l.Out?
The source code is a little complicated to guess it.
There isn't much information in the web about this.
Some information I've consulted:
Shapeless Tests
Shapeless documentation
Your combine method returns what's called a "dependent method type", which just means that its return type depends on one of its arguments—in this case as a path-dependent type that includes l in its path.
In many cases the compiler will statically know something about the dependent return type, but in your example it doesn't. I'll try to explain why in a second, but first consider the following simpler example:
scala> trait Foo { type A; def a: A }
defined trait Foo
scala> def fooA(foo: Foo): foo.A = foo.a
fooA: (foo: Foo)foo.A
scala> fooA(new Foo { type A = String; def a = "I'm a StringFoo" })
res0: String = I'm a StringFoo
Here the inferred type of res0 is String, since the compiler statically knows that the A of the foo argument is String. We can't write either of the following, though:
scala> def fooA(foo: Foo): String = foo.a
<console>:12: error: type mismatch;
found : foo.A
required: String
def fooA(foo: Foo): String = foo.a
^
scala> def fooA(foo: Foo) = foo.a.substring
<console>:12: error: value substring is not a member of foo.A
def fooA(foo: Foo) = foo.a.substring
^
Because here the compiler doesn't statically know that foo.A is String.
Here's a more complex example:
sealed trait Baz {
type A
type B
def b: B
}
object Baz {
def makeBaz[T](t: T): Baz { type A = T; type B = T } = new Baz {
type A = T
type B = T
def b = t
}
}
Now we know that it's not possible to create a Baz with different types for A and B, but the compiler doesn't, so it won't accept the following:
scala> def bazB(baz: Baz { type A = String }): String = baz.b
<console>:13: error: type mismatch;
found : baz.B
required: String
def bazB(baz: Baz { type A = String }): String = baz.b
^
This is exactly what you're seeing. If we look at the code in shapeless.ops.hlist, we can convince ourselves that the LeftFolder we're creating here will have the same type for In and Out, but the compiler can't (or rather won't—it's a design decision) follow us in this reasoning, which means it won't let us treat l.Out as a tuple without more evidence.
Fortunately that evidence is pretty easy to provide thanks to LeftFolder.Aux, which is just an alias for LeftFolder with the Out type member as a fourth type parameter:
def combine[A <: HList](columns: A, suffix: String, separator: String = " and ")(
implicit l: LeftFolder.Aux[
A,
(String, String, String),
columnCombinator.type,
(String, String, String)
]
): String =
columns.foldLeft((suffix, separator, ""))(columnCombinator)._3
(You could also use the type member syntax with plain old LeftFolder in l's type, but that would make this signature even messier.)
The columns.foldLeft(...)(...) part still returns l.Out, but now the compiler statically knows that that's a tuple of strings.
After having read the complete answer from Travis, here is a little variation of his solution:
type CombineTuple = (String, String, String)
def combine[A <: HList](columns: A, suffix: String, separator: String = " and ")(
implicit l: LeftFolder[
A,
CombineTuple,
columnCombinator.type
]
): String =
columns.foldLeft((suffix, separator, ""))(columnCombinator).asInstanceof[CombineTuple]._3
In this way, the implicit signature is shorter, as it is needed in many methods that call this one.
UPDATED: As Travis has explained in comments, it is bestter to use LeftFolder.Aux.
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.