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

Can I avoid excessive generic typing?

7 replies
nilskp
Joined: 2009-01-30,
User offline. Last seen 1 year 27 weeks ago.
Let's say I have a Foo type and a factory for foos. I can model it in this way:
trait Foo[G] {  val g: G }
trait Factory[G, F <: Foo[G]] {   def produce(g: G): F}
But it annoys me to no end that I have to supply G to the Factory. Is there any way to infer G from Foo? E.g.
trait Factory[F <: Foo[_]] {  def produce(g: F.g.type): F}
I'm probably asking something preposterous, but once you deal with various interdependent types, this get's highly annoying.

H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: Can I avoid excessive generic typing?

like this?
trait Foo {
type G
val g: G
}

trait Factory[F <: Foo] {

def produce(g: F#G): F
}

-------- Original-Nachricht --------
> Datum: Thu, 26 Jan 2012 14:43:45 -0600
> Von: Nils Kilden-Pedersen
> An: scala-user
> Betreff: [scala-user] Can I avoid excessive generic typing?

> Let's say I have a Foo type and a factory for foos. I can model it in this
> way:
>
> trait Foo[G] {
> val g: G
> }
>
> trait Factory[G, F <: Foo[G]] {
> def produce(g: G): F
> }
>
> But it annoys me to no end that I have to supply G to the Factory. Is
> there
> any way to infer G from Foo? E.g.
>
> trait Factory[F <: Foo[_]] {
> def produce(g: F.g.type): F
> }
>
> I'm probably asking something preposterous, but once you deal with various
> interdependent types, this get's highly annoying.

Derek Williams 3
Joined: 2011-08-12,
User offline. Last seen 42 years 45 weeks ago.
Re: Can I avoid excessive generic typing?

On my phone so haven't tested, but I am sure you can move the G type parameter down to your produce method, which should infer it properly.

On Jan 26, 2012 1:44 PM, "Nils Kilden-Pedersen" <nilskp@gmail.com> wrote:
Let's say I have a Foo type and a factory for foos. I can model it in this way:
trait Foo[G] {  val g: G }
trait Factory[G, F <: Foo[G]] {   def produce(g: G): F}
But it annoys me to no end that I have to supply G to the Factory. Is there any way to infer G from Foo? E.g.
trait Factory[F <: Foo[_]] {  def produce(g: F.g.type): F}
I'm probably asking something preposterous, but once you deal with various interdependent types, this get's highly annoying.

nilskp
Joined: 2009-01-30,
User offline. Last seen 1 year 27 weeks ago.
Re: Can I avoid excessive generic typing?
On Thu, Jan 26, 2012 at 6:06 PM, Derek Williams <derek@fyrie.net> wrote:

On my phone so haven't tested, but I am sure you can move the G type parameter down to your produce method, which should infer it properly.

I tried, but that didn't work. Could you give an example?  

On Jan 26, 2012 1:44 PM, "Nils Kilden-Pedersen" <nilskp@gmail.com> wrote:
Let's say I have a Foo type and a factory for foos. I can model it in this way:
trait Foo[G] {  val g: G }
trait Factory[G, F <: Foo[G]] {   def produce(g: G): F}
But it annoys me to no end that I have to supply G to the Factory. Is there any way to infer G from Foo? E.g.
trait Factory[F <: Foo[_]] {  def produce(g: F.g.type): F}
I'm probably asking something preposterous, but once you deal with various interdependent types, this get's highly annoying.


nilskp
Joined: 2009-01-30,
User offline. Last seen 1 year 27 weeks ago.
Re: Can I avoid excessive generic typing?
My example was a little too simple. I'm going to try to see if I can get away with this, but I've often found that once you move to abstract type members, you lose all the typing when dealing with the class abstractly. So often that doesn't work.

On Thu, Jan 26, 2012 at 2:57 PM, Dennis Haupt <h-star@gmx.de> wrote:
like this?
       trait Foo {
               type G
               val g: G
       }

       trait Factory[F <: Foo] {

               def produce(g: F#G): F
       }


-------- Original-Nachricht --------
> Datum: Thu, 26 Jan 2012 14:43:45 -0600
> Von: Nils Kilden-Pedersen <nilskp@gmail.com>
> An: scala-user <scala-user@googlegroups.com>
> Betreff: [scala-user] Can I avoid excessive generic typing?

> Let's say I have a Foo type and a factory for foos. I can model it in this
> way:
>
> trait Foo[G] {
>   val g: G
> }
>
> trait Factory[G, F <: Foo[G]] {
>   def produce(g: G): F
> }
>
> But it annoys me to no end that I have to supply G to the Factory. Is
> there
> any way to infer G from Foo? E.g.
>
> trait Factory[F <: Foo[_]] {
>   def produce(g: F.g.type): F
> }
>
> I'm probably asking something preposterous, but once you deal with various
> interdependent types, this get's highly annoying.

Derek Williams 3
Joined: 2011-08-12,
User offline. Last seen 42 years 45 weeks ago.
Re: Can I avoid excessive generic typing?
On Thu, Jan 26, 2012 at 6:16 PM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:
On Thu, Jan 26, 2012 at 6:06 PM, Derek Williams <derek@fyrie.net> wrote:

On my phone so haven't tested, but I am sure you can move the G type parameter down to your produce method, which should infer it properly.

I tried, but that didn't work. Could you give an example?

Something like this? I guess it depends on what you intend to do with it.
Welcome to Scala version 2.9.1.r0-b20110831114755 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_30). Type in expressions to have them evaluated.Type :help for more information.
scala> trait Foo[G] { val g: G }defined trait Foo
scala> trait Factory[F[_] <: Foo[_]] { def produce[G](g: G): F[G] }defined trait Factory
scala> class FooFactory extends Factory[Foo] { def produce[G](_g: G): Foo[G] = new Foo[G] { val g = _g } } defined class FooFactory
scala> val factory = new FooFactory factory: FooFactory = FooFactory@347f2036
scala> factory.produce("bar") res0: Foo[java.lang.String] = FooFactory$$anon$1@3a5e7663
--
Derek Williams
H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: Can I avoid excessive generic typing?

i assumed the thread starter has a set of Foos with different type parameters and wanted each to be created by a matching factory.

in your solution, G is no longer inferred from the factories type parameter X <: Foo[G], you bypass its type parameter. your foofactory just accepts any type and wraps it in a foo

which is why i proposed this:
trait Foo {
type G
val g: G
}

trait Factory[F <: Foo] {

def produce(g: F#G): F
}

that way, a factory only accepts a G that matches the G of its F

and am waiting for yay or nay :)

-------- Original-Nachricht --------
> Datum: Thu, 26 Jan 2012 18:27:50 -0700
> Von: Derek Williams
> An: Nils Kilden-Pedersen
> CC: scala-user
> Betreff: Re: [scala-user] Can I avoid excessive generic typing?

> On Thu, Jan 26, 2012 at 6:16 PM, Nils Kilden-Pedersen
> wrote:
>
> > On Thu, Jan 26, 2012 at 6:06 PM, Derek Williams wrote:
> >
> >> On my phone so haven't tested, but I am sure you can move the G type
> >> parameter down to your produce method, which should infer it properly.
> >>
> > I tried, but that didn't work. Could you give an example?
> >
>
> Something like this? I guess it depends on what you intend to do with it.
>
> Welcome to Scala version 2.9.1.r0-b20110831114755 (Java HotSpot(TM) 64-Bit
> Server VM, Java 1.6.0_30).
> Type in expressions to have them evaluated.
> Type :help for more information.
>
> scala> trait Foo[G] { val g: G }
> defined trait Foo
>
> scala> trait Factory[F[_] <: Foo[_]] { def produce[G](g: G): F[G] }
> defined trait Factory
>
> scala> class FooFactory extends Factory[Foo] { def produce[G](_g: G):
> Foo[G] = new Foo[G] { val g = _g } }
> defined class FooFactory
>
> scala> val factory = new FooFactory
> factory: FooFactory = FooFactory@347f2036
>
> scala> factory.produce("bar")
> res0: Foo[java.lang.String] = FooFactory$$anon$1@3a5e7663
>

nilskp
Joined: 2009-01-30,
User offline. Last seen 1 year 27 weeks ago.
Re: Can I avoid excessive generic typing?
On Fri, Jan 27, 2012 at 2:58 AM, Dennis Haupt <h-star@gmx.de> wrote:
i assumed the thread starter has a set of Foos with different type parameters and wanted each to be created by a matching factory.

in your solution, G is no longer inferred from the factories type parameter X <: Foo[G], you bypass its type parameter. your foofactory just accepts any type and wraps it in a foo

which is why i proposed this:
       trait Foo {
               type G
               val g: G
       }

       trait Factory[F <: Foo] {

               def produce(g: F#G): F
       }

that way, a factory only accepts a G that matches the G of its F

and am waiting for yay or nay :)

Dennis, your solution will work for the example described. Unfortunately it was too simplistic. What I'm generally finding is that I have to lug around lots of type parameters to make a given set of classes type-safe. On the surface, this *seems* unnecessary, as the type information ought to be inferred. However, I'm probably asking the impossible out of frustration :-)
 

-------- Original-Nachricht --------
> Datum: Thu, 26 Jan 2012 18:27:50 -0700
> Von: Derek Williams <derek@fyrie.net>
> An: Nils Kilden-Pedersen <nilskp@gmail.com>
> CC: scala-user <scala-user@googlegroups.com>
> Betreff: Re: [scala-user] Can I avoid excessive generic typing?

> On Thu, Jan 26, 2012 at 6:16 PM, Nils Kilden-Pedersen
> <nilskp@gmail.com>wrote:
>
> > On Thu, Jan 26, 2012 at 6:06 PM, Derek Williams <derek@fyrie.net> wrote:
> >
> >> On my phone so haven't tested, but I am sure you can move the G type
> >> parameter down to your produce method, which should infer it properly.
> >>
> > I tried, but that didn't work. Could you give an example?
> >
>
> Something like this? I guess it depends on what you intend to do with it.
>
> Welcome to Scala version 2.9.1.r0-b20110831114755 (Java HotSpot(TM) 64-Bit
> Server VM, Java 1.6.0_30).
> Type in expressions to have them evaluated.
> Type :help for more information.
>
> scala> trait Foo[G] { val g: G }
> defined trait Foo
>
> scala> trait Factory[F[_] <: Foo[_]] { def produce[G](g: G): F[G] }
> defined trait Factory
>
> scala> class FooFactory extends Factory[Foo] { def produce[G](_g: G):
> Foo[G] = new Foo[G] { val g = _g } }
> defined class FooFactory
>
> scala> val factory = new FooFactory
> factory: FooFactory = FooFactory@347f2036
>
> scala> factory.produce("bar")
> res0: Foo[java.lang.String] = FooFactory$$anon$1@3a5e7663
>
> --
> Derek Williams

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