Get companion object of type parameter

2,003 views
Skip to first unread message

Mitchell Hashimoto

unread,
Mar 5, 2011, 2:51:41 AM3/5/11
to scala...@googlegroups.com
Hello, I'm trying to do something like the following:

class Utility[T] {
def doSomething(): T {
T.staticMethod()
}
}

Where T may be some type like the following:

object Foo {
def staticMethod() = new Foo()
}

I realize various weaknesses of the above but hopefully you get the point :)

I'm probably doing something horribly wrong but I'm hoping to be at
least pointed in the right direction from this list. How would you do
the above?

Thanks,
Mitchell

Lex

unread,
Mar 5, 2011, 3:14:50 AM3/5/11
to Mitchell Hashimoto, scala...@googlegroups.com
You could add getCompanion() to your classes and forward the call.
Another way is to make your companion object implicit and inject it in the Utility class via constructor:

trait OOHack[T] {
  def staticMethod()
}

class Foo
implict object Foo with OOHack[Foo] { ... }

class Utility[T] (implicit val anOOHack: OOHack[T]) {
 def doSomething() {
   
anOOHack.staticMethod()

Alexey Romanov

unread,
Mar 5, 2011, 3:18:25 AM3/5/11
to Mitchell Hashimoto, scala...@googlegroups.com
I don't think it's possible (but would be happy to learn I was wrong).
T could extend a template with a "companion" method, as in
http://www.scala-lang.org/api/current/scala/collection/generic/GenericTraversableTemplate.html,
but even then you would first need an object of the type T to call
this method on.

Yours, Alexey Romanov

Naftoli Gugenheim

unread,
Mar 6, 2011, 8:57:02 PM3/6/11
to Mitchell Hashimoto, scala...@googlegroups.com
Do you mean companion object as used in the scala language, or do you just need types to point you to a factory object?

If the former, do you require top-level types? Either way, you could probably use reflection to find it, although I don't know if all the rules or how likely they are to change.

If the latter, one option is something like (not 100% sure it works):

class Utility[T](implicit factory: Factory[T]) {
  def doSomething: T = factory.method
}

trait Factory[T] {
  def method: T
}

// somewhere else
trait Foo
object Foo {
  implicit def factory: Factory[T] = new Factory[T] { def method = new Foo {} }
}

//Would this work? (No idea)
implicit object Foo extends Factory[T] {
  def method = new Foo

Mitchell Hashimoto

unread,
Mar 6, 2011, 10:37:18 PM3/6/11
to Naftoli Gugenheim, scala...@googlegroups.com
Naftoli,

On Sun, Mar 6, 2011 at 5:57 PM, Naftoli Gugenheim <nafto...@gmail.com> wrote:
> Do you mean companion object as used in the scala language, or do you just
> need types to point you to a factory object?

I suppose you're right, I just want access to call static methods on the class.

I guess it would've helped if I explained my problem, and maybe
someone can recommend a more scala-like way of solving it. I have a
bunch of classes which are supposed to be instantiated by converting
from a Jsoup Element class. So I wanted to enforce that all of the
classes have a companion object which has a method like "fromElement"
to convert to an instance of the class.

I'm still not sure how to do this.

> If the former, do you require top-level types? Either way, you could
> probably use reflection to find it, although I don't know if all the rules
> or how likely they are to change.
> If the latter, one option is something like (not 100% sure it works):
> class Utility[T](implicit factory: Factory[T]) {
>   def doSomething: T = factory.method
> }
> trait Factory[T] {
>   def method: T
> }
> // somewhere else
> trait Foo
> object Foo {
>   implicit def factory: Factory[T] = new Factory[T] { def method = new Foo
> {} }
> }
> //Would this work? (No idea)
> implicit object Foo extends Factory[T] {
>   def method = new Foo
> }

This idea looks interesting ,but I'm still hoping there is a more
concise way to solve my problem above :) Either way, I'll take a
closer look at what you've given me here.

Thanks,
Mitchell

Kevin Wright

unread,
Mar 7, 2011, 3:21:10 AM3/7/11
to Mitchell Hashimoto, scala...@googlegroups.com, Naftoli Gugenheim


On 7 Mar 2011 03:37, "Mitchell Hashimoto" <mitchell....@gmail.com> wrote:
>
> Naftoli,
>
> On Sun, Mar 6, 2011 at 5:57 PM, Naftoli Gugenheim <nafto...@gmail.com> wrote:
> > Do you mean companion object as used in the scala language, or do you just
> > need types to point you to a factory object?
>
> I suppose you're right, I just want access to call static methods on the class.
>
> I guess it would've helped if I explained my problem, and maybe
> someone can recommend a more scala-like way of solving it. I have a
> bunch of classes which are supposed to be instantiated by converting
> from a Jsoup Element class. So I wanted to enforce that all of the
> classes have a companion object which has a method like "fromElement"
> to convert to an instance of the class.
>
> I'm still not sure how to do this.
>

It's a classic use case for type classes. Look at how Numeric, for example, enforces that certain types have a `+` operation.

Reply all
Reply to author
Forward
0 new messages