Basic question about Type parameters contraints

74 views
Skip to first unread message

Żabojad

unread,
Mar 9, 2016, 10:26:52 AM3/9/16
to Haxe
I'm trying to implement Type parameters contraints to enforce a function parameter to have a field named "type". However, this parameter is can be of many types of Dynamic objects

typedef Action = {
    type : String
}
typedef ActionOne = Action;
typedef ActionTwo = {
    > Action,
    otherField : String
}
static public function execute<T:(Action)>(a : T) : State {
    switch (a.type) {
         case "one":
             // ...
         case "two":
             doSomething(a.otherField);
    }
}

However this will not compile, saying that: execute.T has no field otherField.

It seems that it would be the same if my execute method signature would be:

static public function execute(a : Action) : State {

I'm certainly missing something as I do not really see the additional value of using Type parameters contraints here...

Clark Jones

unread,
Mar 9, 2016, 4:02:07 PM3/9/16
to Haxe
I think you'd have to do something like  ... execute<T:(Action, ActionTwo)> or cast a to the type you're expecting for  this to work. What your doing is like expecting an arg of type SuperClass and trying to access a SubClass property with out any sort of casting

Żabojad

unread,
Mar 11, 2016, 4:38:41 AM3/11/16
to Haxe
Let's consider I have ActionTwo, ActionThree, + many other...

And that all those structure have only one common field: type

I understood that Type parameters contraints aimed at requiring the existence of some fields on the parameters passed to a function without having to actually type it.

Here, I only want to require the existence of this "type" field. In other words, I would like T to be a Dynamic that has at least a type field.

If that's not possible, I do not see the benefit of the Type parameters constraints and the real difference in use between:

static public function execute<T:(Action)>(a : T) : State {

and:

static public function execute(a : Action) : State {


clemos

unread,
Mar 11, 2016, 7:06:47 AM3/11/16
to haxe...@googlegroups.com
Hi,

The problem is you want to type a variable based on a runtime value (the "type" value).
This is not really possible to "model" this type of constraint in Haxe

If it were me, I would just use enums to model the different action types.
Assuming your objects need to be { type : String } (because you get them from whatever API), 
you need to implement a runtime conversion mechanism from these objects to enum, probably including validation.

Here's how I would do:

It may be possible to add extra constraints using @:enum abstracts à la hxnodejs' Event,
but it's slightly beyond my voodoo :)

Best,
Clément


--
To post to this group haxe...@googlegroups.com
http://groups.google.com/group/haxelang?hl=en
---
You received this message because you are subscribed to the Google Groups "Haxe" group.
For more options, visit https://groups.google.com/d/optout.

Mark Knol

unread,
Mar 18, 2016, 8:01:39 AM3/18/16
to Haxe
Hi Żabojad, not an answer to your question but one of the benefit of the Type parameters is for inference of types.

Imaging these two cases:

static public function execute1<T:Action>(a : T) : T {}
static public function execute2(a : Action) : Action {}

Lets say you have ActionB which extends Action.

var sample1 = execute1(myActionA);
// type of 'sample1': Action

var sample2 = execute1(myActionB);
// type of 'sample2': ActionB


var sample3 = execute2(myActionA);
// type of 'sample3': Action

var sample4 = execute2(myActionB);
// type of 'sample4': Action

As you see, without Typed parameters the type is always inferred from as Action. Otherwise it is nicely inferred as the given type (ActionB).

Check out this example:

Simon Krajewski

unread,
Mar 18, 2016, 8:11:25 AM3/18/16
to haxe...@googlegroups.com
To expand on that, consider a compare function:

static function compare(a:Action, b:Action) { }
static function compare<T:Action>(a:T, b:T) { }

The first one allows calling `compare(new Action1(), new Action2())` assuming both extend Action. The second one does not allow that.

Simon
Reply all
Reply to author
Forward
0 new messages