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

Implicit Scope: Type Params vs Type Members

5 replies
Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
I've been experimenting with using type members, rather than type parameters, through the Scalaz type class hierarchy. Together with dependent method types, this can afford better type inference. Compare the usage of `Functor#compose` in this gist [1] against similar usages [2] when using type parameters.

One small problem with this encoding, is that the implicit scope no longer includes the classified types.

  trait TC_ { type F }
  type TC[G] = TC_ { type F = G }

  trait Data
  object Data {
    implicit val instance = new TC { type F = Data }
  }

  implicitly[TC[Data]] // fail, need to import Data._

In the interest of making type parameters and type members more easily interchangable, would it make sense to include the RHS of type members to the
parts of a type?

-jason

[1] https://gist.github.com/1458981
[2] https://github.com/scalaz/scalaz/blob/scalaz-seven/example/src/main/scala/scalaz/example/WordCount.scala#L35
milessabin
Joined: 2008-08-11,
User offline. Last seen 33 weeks 3 days ago.
Re: Implicit Scope: Type Params vs Type Members

On Sun, Dec 11, 2011 at 7:18 AM, Jason Zaugg wrote:
> I've been experimenting with using type members, rather than type
> parameters, through the Scalaz type class hierarchy. Together with dependent
> method types, this can afford better type inference. Compare the usage of
> `Functor#compose` in this gist [1] against similar usages [2] when using
> type parameters.
>
> One small problem with this encoding, is that the implicit scope no longer
> includes the classified types.
>
>   trait TC_ { type F }
>   type TC[G] = TC_ { type F = G }
>
>   trait Data
>   object Data {
>     implicit val instance = new TC { type F = Data }
>   }
>
>   implicitly[TC[Data]] // fail, need to import Data._
>
> In the interest of making type parameters and type members more easily
> interchangable, would it make sense to include the RHS of type members to
> the parts of a type?

Very useful: anything which makes type parameters and type members
more interchangeable would be extremely welcome IMO.

That said, there is a workaround for your situation,

trait TCHelper[TC[_], G] {
def tc : TC[G]
}

implicit def tc[TC[_], G](implicit helper : TCHelper[TC, G]) : TC[G]
= helper.tc

Then modify the definition of your Data object like so,

object Data {
val instance = new TC_ { type F = Data }
implicit val helper = new TCHelper[TC, Data] {
def tc = instance
}
}

and now implicitly[TC[Data]] will be fine without needing an explicit
import from Data.

Cheers,

Miles

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: Implicit Scope: Type Params vs Type Members

I am very sympathetic to the argument that type members and type
parameters should be interchangeable. But the implicit scope is
already quite large; increasing it further to type members could
involve unacceptable slowdowns of the compiler.

Cheers

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Implicit Scope: Type Params vs Type Members

On Sun, Dec 11, 2011 at 6:13 AM, martin odersky wrote:
> I am very sympathetic to the argument that type members and type
> parameters should be interchangeable. But the implicit scope is
> already quite large; increasing it further to type members could
> involve unacceptable slowdowns of the compiler.

Speaking of messing with implicit scope (not that you were) am I the
only one whose intuition has always expected the compiler to find
implicit conversions in one place above all else, which it doesn't?

class B { def bippy = 5 }
class A { implicit def atob(x: A): B = new B }
val a = new A
a.bippy

Why there above anywhere else? The intuition follows the path of
cogito ergo sum: "I'm invoking a method on an instance, therefore the
methods of that instance are invokable."

Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
Re: Implicit Scope: Type Params vs Type Members
On Mon, Dec 12, 2011 at 7:16 AM, Paul Phillips <paulp [at] improving [dot] org> wrote:
On Sun, Dec 11, 2011 at 6:13 AM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:
> I am very sympathetic to the argument that type members and type
> parameters should be interchangeable. But the implicit scope is
> already quite large; increasing it further to type members could
> involve unacceptable slowdowns of the compiler.

Speaking of messing with implicit scope (not that you were) am I the
only one whose intuition has always expected the compiler to find
implicit conversions in one place above all else, which it doesn't?

 class B { def bippy = 5 }
 class A { implicit def atob(x: A): B = new B }
 val a = new A
 a.bippy

Why there above anywhere else? The intuition follows the path of
cogito ergo sum: "I'm invoking a method on an instance, therefore the
methods of that instance are invokable."

A conversion method that doesn't refer to `this` could just as well be in the companion, where it would be in the implicit scope. As an instance method, this would make more sense to me:

class A { implicit def tob: B = new B }
a.bippy

-jason
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Implicit Scope: Type Params vs Type Members

On Sun, Dec 11, 2011 at 1:44 PM, Jason Zaugg wrote:
> class A { implicit def tob: B = new B }
> a.bippy

You're right, that's way better.

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