Question about type parameters

345 views
Skip to first unread message

Żabojad

unread,
Jul 23, 2012, 6:39:22 AM7/23/12
to haxe...@googlegroups.com
Hi,

How can I check if a given variable is an instance of a specific 'type parametrized' class or implements a 'type parametrized' interface ? 

For example, How can I check that a given var is a Array<Int> ?

Std.is doesn't accept the type parameter : Std.is(a,Array<String>) won't compile.

Thanks,

Thomas


Żabojad

unread,
Jul 23, 2012, 8:19:59 AM7/23/12
to haxe...@googlegroups.com
static function compareArrays<U,T>(a:Array<U>, b:Array<T>)
{
return U == T;
}

./Test.hx:32: characters 9-10 : Type parameter U is only available at compilation and is not a runtime value
./Test.hx:32: characters 14-15 : Type parameter T is only available at compilation and is not a runtime value 

:( !

Let's say I have a collection of different kinds of Arrays (for example : Array<Int>, Array<String> and Array<CustomClass>) and I want to select/filter only the Array<Int> out of this collection.

How should I do ?

Cauê Waneck

unread,
Jul 23, 2012, 8:28:22 AM7/23/12
to haxe...@googlegroups.com
Hey Thomas!

The issue is the same as in Java - most Haxe implementations don't have any reference of type parameters at runtime.

What you could do is use something like Simon's hxunify lib:  https://github.com/Simn/hxunify . But it would be quite heavy in the runtime.
Also depending on your use case you may be able to do something like

if (Std.is(a[0], Int)) ... or

if (Std.is(a[0], Type.getClass(b[0]));

though remember that if they are empty there will be no way to know ;)

Cheers!
Cauê

2012/7/23 Żabojad <thomas.fet...@googlemail.com>

Max

unread,
Jul 23, 2012, 9:09:44 AM7/23/12
to haxe...@googlegroups.com
> For example, How can I check that a given var is a Array<Int> ?

var a:Array<Int>;

You have two choices here: If class (in your case Array) is @:generic

trace(Std.string(a)); // traces Array_Int

trace
($type(a)); // traces [Object Array_Int];




However, in most cases, your (or external class) is not @:generic. In that case you can use macro

class CTTI { //compile time typo info
   
@:macro
   
public static function get_type(instance) {
       
var b:Dynamic;
       
switch(Context.typeof(instance)) {
           
case TType(t, p): b = t.get().name;
           
case TInst(i, p): // b = i.get().name;
               
switch(p[0]){case TInst(c,d): b=c.get().name;
                           
default:null;};
           
case TDynamic(d): b="dyn";
           
case TAnonymous(a): b="anon";
           
case TMono(m): b="mono";
           
default: b=null;
       
}
       
return Context.makeExpr(b, haxe.macro.Context.currentPos());
   
}
}


You can use it like

        var c:String = CTTI.get_type(a);
        trace
("macro: " + c);

Since macros are executed at compile time, you can use macro output for static variables (where applicable), etc.

Important: you can't observe type parameter inside the class which implements it (not without live instance).

Żabojad

unread,
Jul 23, 2012, 10:02:24 AM7/23/12
to haxe...@googlegroups.com
Well, in my case, I'm using custom type parameterized classes, not Arrays. Also I would need to know the type parameter at runtime. I thus think that type parameter might not be the feature I should use for what I want to do :)...

Thank you both anyway :) !


Cauê Waneck

unread,
Jul 25, 2012, 9:39:09 AM7/25/12
to haxe...@googlegroups.com
maybe you can pass the Class<T> type at object creation then?

Something like:

class Test<T>
{
public var cls(default, null):Class<T>;
public function new(cls) { this.cls = cls; }
}

... later ...

if (myTestObject.cls == Int) { ... }

2012/7/23 Żabojad <thomas.fet...@googlemail.com>:
Reply all
Reply to author
Forward
0 new messages