How to find a type parameter at runtime? (Generics / Manifest)

View: New views
9 Messages — Rating Filter:   Alert me  

How to find a type parameter at runtime? (Generics / Manifest)

by Lachlan Cotter :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Hi,

I have a generic wrapper type Foo[X].

For a given instance of Foo[X] I want get the class of X. I have to be able to do this without actually examining the wrapped value because it might be null.

For example:

val x = new Foo[String]()
x.wrappedType // Class[String]

From what I’ve read, I understand that this is what Manifests might be good for, but after re-reading all the info I can find on them several times, I’m still hitting walls.

Is what I’m trying to do even possible?



Cheers,
Lach

Re: How to find a type parameter at runtime? (Generics / Manifest)

by Paul Phillips-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, Nov 01, 2009 at 02:46:39PM +1100, Lachlan Cotter wrote:
> I have a generic wrapper type Foo[X].
>
> For a given instance of Foo[X] I want get the class of X.

We really need a decent faq going somewhere.  (Not a criticism of you, a
general plea for it to exist.) This is 2.8:

scala> class Foo[X](implicit val m: Manifest[X])    
defined class Foo

scala> new Foo[String]() m  
res0: Manifest[String] = java.lang.String

scala> res0.erasure
res1: java.lang.Class[_] = class java.lang.String

--
Paul Phillips      | Those who can make you believe absurdities
Stickler           | can make you commit atrocities.
Empiricist         |     -- Voltaire
slap pi uphill!    |----------* http://www.improving.org/paulp/ *----------

Re: How to find a type parameter at runtime? (Generics / Manifest)

by Naftoli Gugenheim :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I think he wants res0.typeArguments.

On Sun, Nov 1, 2009 at 12:30 AM, Paul Phillips <paulp@...> wrote:
On Sun, Nov 01, 2009 at 02:46:39PM +1100, Lachlan Cotter wrote:
> I have a generic wrapper type Foo[X].
>
> For a given instance of Foo[X] I want get the class of X.

We really need a decent faq going somewhere.  (Not a criticism of you, a
general plea for it to exist.) This is 2.8:

scala> class Foo[X](implicit val m: Manifest[X])
defined class Foo

scala> new Foo[String]() m
res0: Manifest[String] = java.lang.String

scala> res0.erasure
res1: java.lang.Class[_] = class java.lang.String

--
Paul Phillips      | Those who can make you believe absurdities
Stickler           | can make you commit atrocities.
Empiricist         |     -- Voltaire
slap pi uphill!    |----------* http://www.improving.org/paulp/ *----------


Re: How to find a type parameter at runtime? (Generics / Manifest)

by Paul Phillips-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, Nov 01, 2009 at 12:41:34AM -0400, Naftoli Gugenheim wrote:
> I think he wants res0.typeArguments.

Really? He wanted Nil? I could have saved him some trouble then.

--
Paul Phillips      | Before a man speaks it is always safe to assume
Future Perfect     | that he is a fool.  After he speaks, it is seldom
Empiricist         | necessary to assume it.
pull his pi pal!   |     -- H. L. Mencken

Re: How to find a type parameter at runtime? (Generics / Manifest)

by Naftoli Gugenheim :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Never mind, I reread his post. Don't ask why I thought Foo[String] was the type parameter to something else.

On Sun, Nov 1, 2009 at 12:50 AM, Paul Phillips <paulp@...> wrote:
On Sun, Nov 01, 2009 at 12:41:34AM -0400, Naftoli Gugenheim wrote:
> I think he wants res0.typeArguments.

Really? He wanted Nil? I could have saved him some trouble then.

--
Paul Phillips      | Before a man speaks it is always safe to assume
Future Perfect     | that he is a fool.  After he speaks, it is seldom
Empiricist         | necessary to assume it.
pull his pi pal!   |     -- H. L. Mencken


Re: How to find a type parameter at runtime? (Generics / Manifest)

by Lachlan Cotter :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks for your speedy response Paul,

This looks encouraging.

I had actually tried using that syntax for the Manifest with 2.7.7 but the compiler complained that there was no implicit argument in scope:

no implicit argument matching parameter type scala.reflect.Manifest[T] was found

Does it work with the current stable release or do I need 2.8?



Cheers,
Lach




On 01/11/2009, at 3:30 PM, Paul Phillips wrote:

On Sun, Nov 01, 2009 at 02:46:39PM +1100, Lachlan Cotter wrote:
I have a generic wrapper type Foo[X].

For a given instance of Foo[X] I want get the class of X.

We really need a decent faq going somewhere.  (Not a criticism of you, a
general plea for it to exist.) This is 2.8:

scala> class Foo[X](implicit val m: Manifest[X])     
defined class Foo

scala> new Foo[String]() m  
res0: Manifest[String] = java.lang.String

scala> res0.erasure
res1: java.lang.Class[_] = class java.lang.String

--
Paul Phillips      | Those who can make you believe absurdities
Stickler           | can make you commit atrocities.
Empiricist         |     -- Voltaire
slap pi uphill!    |----------* http://www.improving.org/paulp/ *----------


Re: How to find a type parameter at runtime? (Generics / Manifest)

by Germán :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi, 

As far I know, this is only available in scala 2.8 

Regards, 
Germán.


On Sun, Nov 1, 2009 at 9:46 AM, Lachlan Cotter <lach@...> wrote:
Thanks for your speedy response Paul,

This looks encouraging.

I had actually tried using that syntax for the Manifest with 2.7.7 but the compiler complained that there was no implicit argument in scope:

no implicit argument matching parameter type scala.reflect.Manifest[T] was found

Does it work with the current stable release or do I need 2.8?



Cheers,
Lach




On 01/11/2009, at 3:30 PM, Paul Phillips wrote:

On Sun, Nov 01, 2009 at 02:46:39PM +1100, Lachlan Cotter wrote:
I have a generic wrapper type Foo[X].

For a given instance of Foo[X] I want get the class of X.

We really need a decent faq going somewhere.  (Not a criticism of you, a
general plea for it to exist.) This is 2.8:

scala> class Foo[X](implicit val m: Manifest[X])     
defined class Foo

scala> new Foo[String]() m  
res0: Manifest[String] = java.lang.String

scala> res0.erasure
res1: java.lang.Class[_] = class java.lang.String

--
Paul Phillips      | Those who can make you believe absurdities
Stickler           | can make you commit atrocities.
Empiricist         |     -- Voltaire
slap pi uphill!    |----------* http://www.improving.org/paulp/ *----------



Re: How to find a type parameter at runtime? (Generics / Manifest)

by Arthur Peters :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Manifests work fine in 2.7. I've used them several times.

The issue may be that you have to have a Manifest implicit available either by using a explicit compile time known parameter, or my having another implicitly passed manifest in scope. For example:

(In Scala 2.8)
scala> def f1[T]()(implicit m : Manifest[T]) = println(m.erasure)
f1: [T]()(implicit m: Manifest[T])Unit

scala> def f2[T]() = f1[T]()                                    
<console>:5: error: could not find implicit value for parameter m: Manifest[T]
       def f2[T]() = f1[T]()
                          ^
This will give you the same compiler error you see. To fix it you need to add an implicit Manifest to f2 at well.

scala> def f3[T]()(implicit m : Manifest[T]) = f1[T]()
f3: [T]()(implicit m: Manifest[T])Unit

-Arthur

PS: In scala 2.7 it's basically the same:
scala> def f1[T]()(implicit m : Manifest[T]) = println(m.erasure)
f1: [T]()(implicit scala.reflect.Manifest[T])Unit

scala> def f2[T]() = f1[T]()                                    
<console>:6: error: no implicit argument matching parameter type scala.reflect.Manifest[T] was found.
       def f2[T]() = f1[T]()
                     ^

scala> def f3[T]()(implicit m : Manifest[T]) = f1[T]()                                                                                      
f3: [T]()(implicit scala.reflect.Manifest[T])Unit


On Sun, Nov 1, 2009 at 10:11 AM, Germán Ferrari <german.ferrari@...> wrote:
Hi, 

As far I know, this is only available in scala 2.8 

Regards, 
Germán.


On Sun, Nov 1, 2009 at 9:46 AM, Lachlan Cotter <lach@...> wrote:
Thanks for your speedy response Paul,

This looks encouraging.

I had actually tried using that syntax for the Manifest with 2.7.7 but the compiler complained that there was no implicit argument in scope:

no implicit argument matching parameter type scala.reflect.Manifest[T] was found

Does it work with the current stable release or do I need 2.8?



Cheers,
Lach




On 01/11/2009, at 3:30 PM, Paul Phillips wrote:

On Sun, Nov 01, 2009 at 02:46:39PM +1100, Lachlan Cotter wrote:
I have a generic wrapper type Foo[X].

For a given instance of Foo[X] I want get the class of X.

We really need a decent faq going somewhere.  (Not a criticism of you, a
general plea for it to exist.) This is 2.8:

scala> class Foo[X](implicit val m: Manifest[X])     
defined class Foo

scala> new Foo[String]() m  
res0: Manifest[String] = java.lang.String

scala> res0.erasure
res1: java.lang.Class[_] = class java.lang.String

--
Paul Phillips      | Those who can make you believe absurdities
Stickler           | can make you commit atrocities.
Empiricist         |     -- Voltaire
slap pi uphill!    |----------* http://www.improving.org/paulp/ *----------




Re: How to find a type parameter at runtime? (Generics / Manifest) (solved)

by Lachlan Cotter :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks Arthur — that's exactly what the problem was.

I needed to declare the implicit manifest parameter on the overloaded constructors and the constructors of subclasses.

Thanks for turning my bar green.


Best,
Lach


On 02/11/2009, at 5:01 AM, Arthur Peters wrote:

Manifests work fine in 2.7. I've used them several times.

The issue may be that you have to have a Manifest implicit available either by using a explicit compile time known parameter, or my having another implicitly passed manifest in scope. For example:

(In Scala 2.8)
scala> def f1[T]()(implicit m : Manifest[T]) = println(m.erasure)
f1: [T]()(implicit m: Manifest[T])Unit

scala> def f2[T]() = f1[T]()                                     
<console>:5: error: could not find implicit value for parameter m: Manifest[T]
       def f2[T]() = f1[T]()
                          ^
This will give you the same compiler error you see. To fix it you need to add an implicit Manifest to f2 at well.

scala> def f3[T]()(implicit m : Manifest[T]) = f1[T]()
f3: [T]()(implicit m: Manifest[T])Unit

-Arthur

PS: In scala 2.7 it's basically the same: 
scala> def f1[T]()(implicit m : Manifest[T]) = println(m.erasure)
f1: [T]()(implicit scala.reflect.Manifest[T])Unit

scala> def f2[T]() = f1[T]()                                     
<console>:6: error: no implicit argument matching parameter type scala.reflect.Manifest[T] was found.
       def f2[T]() = f1[T]()
                     ^

scala> def f3[T]()(implicit m : Manifest[T]) = f1[T]()                                                                                       
f3: [T]()(implicit scala.reflect.Manifest[T])Unit