This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Type classes and implicits

7 replies
Ka Ter
Joined: 2011-10-05,
User offline. Last seen 42 years 45 weeks ago.

Hi all,

I'm playing with type classes and implicits and don't understand why
both of the println lines below produce the compiler error:

could not find implicit value for evidence parameter of type
GenericBased[scala.collection.immutable.Set]

I surely understand the message but I don't understand why the mentioned
type could not be found. Why can't the compiler relate a Set with a
Traversable? Any thoughts?

(I need the GenericBasedWrapper only, as Scala doesn't support some kind
of implicit infix functions).

My code:
=========
import scala.collection.parallel.ParIterable

object Test extends App
{
implicit val traversableBased = TraversableBased
implicit val parallelBased = ParallelBased

implicit def toGenericBasedWrapper[A, C[A] : GenericBased](source:
C[A]): GenericBasedWrapper[A, C] = new GenericBasedWrapper[A, C](source)

println(Set[Int](1, 2, 3).doSomething((set: Set[Int]) => set.map(a
=> a + 1)))
println(Set[Int](1, 2, 3).doSomething(set => set.map(a => a + 1)))
}

class GenericBased[+C[_]]
{
def doSomething[A](source: C[A], f: C[A] => C[A]): C[A] = f(source)
}

class GenericBasedWrapper[A, +C[_]: GenericBased](source: C[A])
{
def doSomething(f: C[A] => C[A]): C[A] =
implicitly[GenericBased[C]].doSomething[A](source, f)
}

object TraversableBased extends GenericBased[Traversable]
object ParallelBased extends GenericBased[ParIterable]

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Type classes and implicits

On Thu, Jan 26, 2012 at 8:52 AM, Ka Ter wrote:
> I'm playing with type classes and implicits and don't understand why
> both of the println lines below produce the compiler error:
>
> could not find implicit value for evidence parameter of type
> GenericBased[scala.collection.immutable.Set]

You are to some extent being misled by the fact that this error is
discovered before the other errors and compilation halts before the
later ones are reported. Because they might have been helpful. You
can't write a class like this:

trait GenericBased[+C[_]] {
def doSomething[A](source: C[A], f: C[A] => C[A]): C[A]
}

If you compile that in isolation you will see some of the errors you
didn't see, and after coming to terms with variance you will most
likely see why the implicit wasn't found.

Ka Ter
Joined: 2011-10-05,
User offline. Last seen 42 years 45 weeks ago.
Re: Type classes and implicits

ok, thanks. I see it now. I just added the co-variance in order to see
if anything changes.

Well, without the misplaced co-variances, is there any way to get this
kind of code working? Is there a way to tell the context bound that it
also should match sub-types of a Traversable?

import scala.collection.parallel.ParIterable

object Test extends App
{
implicit val traversableBased = TraversableBased
implicit val parallelBased = ParallelBased

implicit def toGenericBasedWrapper[A, C[A] : GenericBased](source:
C[A]) = new GenericBasedWrapper[A, C](source)

println(Set[Int](1, 2, 3).doSomething((set: Set[Int]) => set.map(a
=> a + 1)))
println(Set[Int](1, 2, 3).doSomething(set => set.map(a => a + 1)))
}

class GenericBased[C[_]]
{
def doSomething[A](source: C[A], f: C[A] => C[A]): C[A] = f(source)
}

class GenericBasedWrapper[A, C[_]: GenericBased](source: C[A])
{
def doSomething(f: C[A] => C[A]): C[A] =
implicitly[GenericBased[C]].doSomething[A](source, f)
}

object TraversableBased extends GenericBased[Traversable]
object ParallelBased extends GenericBased[ParIterable]

Best Regards

Ka Ter

Am 26.01.2012 18:06, schrieb Paul Phillips:
> On Thu, Jan 26, 2012 at 8:52 AM, Ka Ter wrote:
>> I'm playing with type classes and implicits and don't understand why
>> both of the println lines below produce the compiler error:
>>
>> could not find implicit value for evidence parameter of type
>> GenericBased[scala.collection.immutable.Set]
> You are to some extent being misled by the fact that this error is
> discovered before the other errors and compilation halts before the
> later ones are reported. Because they might have been helpful. You
> can't write a class like this:
>
> trait GenericBased[+C[_]] {
> def doSomething[A](source: C[A], f: C[A] => C[A]): C[A]
> }
>
> If you compile that in isolation you will see some of the errors you
> didn't see, and after coming to terms with variance you will most
> likely see why the implicit wasn't found.

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Type classes and implicits

On Thu, Jan 26, 2012 at 9:21 AM, Ka Ter wrote:
> Well, without the misplaced co-variances, is there any way to get this
> kind of code working? Is there a way to tell the context bound that it
> also should match sub-types of a Traversable?

The way you say "also match sub-types of a Traversable" is to make C
covariant. But that means you have to use C covariantly. You are
using it in all possible positions, which means it must be invariant.
Your goals are irreconcilable.

Also, you can rework this code so it is sound and you will most likely
still be disappointed because the compiler won't select the implicit
you want in the face of contravariance. See
http://scala-programming-language.1934581.n4.nabble.com/scala-Implicit-P...
and others.

d_m
Joined: 2010-11-11,
User offline. Last seen 35 weeks 2 days ago.
Re: Type classes and implicits

On Thu, Jan 26, 2012 at 10:46:09AM -0800, Paul Phillips wrote:
> http://scala-programming-language.1934581.n4.nabble.com/scala-Implicit-P...

Reading through that saga again today, it is just as depressing as when
I read it before.

Type inference, contravariance, can't we all just get along?

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Type classes and implicits

On Thu, Jan 26, 2012 at 11:21 AM, Erik Osheim wrote:
> Type inference, contravariance, can't we all just get along?

I heard a rumor that a certain someone had come around about the
definition of specificity and that now it's just a matter of getting
from here to there, but I do not actually know if this is true.

Ka Ter
Joined: 2011-10-05,
User offline. Last seen 42 years 45 weeks ago.
Re: Type classes and implicits

Thank you Phil for your comments.

Best Regards

Ka Ter

Am 26.01.2012 19:46, schrieb Paul Phillips:
> On Thu, Jan 26, 2012 at 9:21 AM, Ka Ter wrote:
>> Well, without the misplaced co-variances, is there any way to get this
>> kind of code working? Is there a way to tell the context bound that it
>> also should match sub-types of a Traversable?
> The way you say "also match sub-types of a Traversable" is to make C
> covariant. But that means you have to use C covariantly. You are
> using it in all possible positions, which means it must be invariant.
> Your goals are irreconcilable.
>
> Also, you can rework this code so it is sound and you will most likely
> still be disappointed because the compiler won't select the implicit
> you want in the face of contravariance. See
> http://scala-programming-language.1934581.n4.nabble.com/scala-Implicit-P...
> and others.

Kris Nuttycombe
Joined: 2009-01-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Type classes and implicits
Oh, paulp, you are such a tease!
Great news though, however remote "there" may be.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland