Construction of generic types WITH arguments

Hey :slight_smile:. Anybody willing to give me a helping hand in accomplishing this using generics? I feel I’ve come some distance when it comes to generics and Haxe in the past week, but I’ve hit a road block again. I’ll keep digging but maybe some of you has an excavator of knowledge for me :smiley:

During the past 4 hours I’ve been trying to invoke the constructor of a type T(name: String, someEnum: SomeEnum) passed into a BuilderClass<T>. I’ve been experimenting with Constraints during the past couple of days. I know that all my types T will satisfy the condition of having these two arguments: name: String, someEnum: SomeEnum)

Currently I’m stuck with //Error:(50, 3) build.T should be BuilderClass.T

I tried different ways of enforcing constraints on BuilderClass. They’re all in the comments below. Nothing worked so far.

I posted the current state of my experiment on try.haxe for your code coloring satisafaction :smiley: . It doesn’t compile due to missing @:generic support so I’ll be posting the code here too


class Main
{
	static function main ()
	{
		var triggerClass: TriggerClass = new TriggerClass("abc");
		trace(triggerClass.toStringDump());
	}
}

class TriggerClass extends BuilderClass<WantToBeBuilt>
{
	public function new (name: String)
	{
		super(name);
		super.build(name, SomeEnum.Member1); //Commented out because it crashes.
	}

	public function toStringDump(): String
	{
		return super.toString();
	}
}

//This is just some idea I had to force constructor when Constructible didn't work.
//This complains about T, if I remove T, it says it should have a type. Setting Void works but I get other errors.
//BuilderClass<T:{function new(desc: String, someEnum: SomeEnum): T; function toStringDump (): String;}>

//This results in the same build.T should be BuilderClass.T error
//class BuilderClass<T:haxe.Constraints.Constructible<String->SomeEnum->Void>>

//The class declaration below shows an error saying 'unexpected {'.
//How can I force both Constructibe AND function constraints?
//class BuilderClass<T:haxe.Constraints.Constructible<String->SomeEnum->Void> {function toStringDump (): String;}>

class BuilderClass<T:{function toStringDump (): String;}>
{
	public var name: String;
	public var instance: T;

	public function new (name: String)
	{
		this.name = name;
	}

	@:generic
	public function build<T:haxe.Constraints.Constructible<String->SomeEnum->Void>>
	(desc: String, someEnum: SomeEnum): Void
	{
		instance = new T(desc, someEnum); //Error:(50, 3) build.T should be BuilderClass.T
	}

	public function toString(): String
	{
		return "BuilderClass name: " + name;// + " instance of T " + instance.toStringDump();
	}
}

class WantToBeBuilt
{
	public var desc: String;
	public var someEnum: SomeEnum;

	public function new (desc: String, someEnum: SomeEnum)
	{
		this.desc = desc;
		this.someEnum = someEnum;
	}

	public function toStringDump(): String
	{
		return desc + " " + someEnum.getName();
	}
}

enum SomeEnum
{
	Member1;
	Member2;
}

Your T in BuilderClass and build aren’t the same, you need to put the Constructible constraint on BuilderClass.

To have both constraint you can separate them with commas for haxe 3 and & for haxe 4:

class BuilderClass<T:{function toStringDump (): String;} & Constructible<String->SomeEnum->Void>>
class BuilderClass<T:({function toStringDump (): String;}, Constructible<String->SomeEnum->Void>)>
1 Like

Thanks for helping out @ibilon :slight_smile:. I gave it another try but still get errors. I moved the call to build into the BuilderClass too, but this didn’t help either.

Hm, I’m going to dig into abstract a bit. Perhaps I can wrap the two in each other somehow to accomplish this. I’m a bit all over the place ATM so any pointer is very welcomed!

The new version is here:

Or here:


class Main
{
	static function main ()
	{
		var triggerClass: TriggerClass = new TriggerClass("abc");
		trace(triggerClass.toStringDump());
	}
}

enum SomeEnum
{
	Member1;
	Member2;
}


class WantToBeBuilt
{
	public var desc: String;
	public var someEnum: SomeEnum;

	public function new (desc: String, someEnum: SomeEnum)
	{
		this.desc = desc;
		this.someEnum = someEnum;
	}

	public function toStringDump(): String
	{
		return desc + " " + someEnum.getName();
	}
}

class BuilderClass<T:haxe.Constraints.Constructible<String->SomeEnum->Void> & {function toStringDump (): String;}>
{
	public var name: String;
	public var instance: T;

	public function new (name: String)
	{
		this.name = name;
		//Error:(54, 3) Constraint check failure for
		//build.T haxe.Constructible<(String, SomeEnum) -> Void> should be { toStringDump : Void -> String }
		build(name, SomeEnum.Member1);
		//build<T>(name, SomeEnum.Member1); //Error:(54, 26) Unexpected . (no other errors)
	}

	@:generic
	public function build<T:haxe.Constraints.Constructible<String -> SomeEnum -> Void> & {function toStringDump (): String;}>
	(desc: String, someEnum: SomeEnum): Void
	{
		instance = new T(desc, someEnum); //Error:(61, 3) build.T should be BuilderClass.T
	}

	public function toString(): String
	{
		return "BuilderClass name: " + name;
	}
}

class TriggerClass extends BuilderClass<WantToBeBuilt>
{
	public function new (name: String)
	{
		super(name);
	}

	public function toStringDump(): String
	{
		return super.toString();
	}
}

You need to make the BuilderClass class generic (so it can construct the T),
and not add another template on the function, otherwise it’s not the same T as the class.

2 Likes

That’s some first class support right here Valentin! :slight_smile:. Thank you! If my project will give me any money, I promise (with witnesses) that I’m going to donate to the Haxe foundation :slight_smile:

Also, I guess I now understand why try.haxe doesn’t work with some of my samples. It still uses Haxe 3.

This has options where you can select Haxe version: http://try-haxe.mrcdk.com/

2 Likes

Thanks! That same domain was given to me yesterday evening as I was hunting an issue with generics & constraints in IJ (broken due to Haxe 4 I think). Hm, I see it stops at H4 p1. That’s about 4 versions ago but hey, it’s still better than nothing! :smiley:

Yes, but it also always has the most recent nightly builds available (from Haxe git builds), which are even more recent than 4.0.0-rc.1:

1 Like

Ah, true that, didn’t look at the dates :smiley:. One of these days “ima gettin meself” a quiet office, 8 hours of free time per day and then I’m going to quit multitasking like a madman and start taking things slower. Until then… mea culpa :smiley: