Hey . 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
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 . 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;
}
Thanks for helping out @ibilon. 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.
That’s some first class support right here Valentin! . Thank you! If my project will give me any money, I promise (with witnesses) that I’m going to donate to the Haxe foundation
Also, I guess I now understand why try.haxe doesn’t work with some of my samples. It still uses Haxe 3.
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!
Ah, true that, didn’t look at the dates . 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