unification confusion

93 просмотра
Перейти к первому непрочитанному сообщению

Adrian Veith

не прочитано,
20 июн. 2016 г., 05:31:5220.06.2016
– Haxe
Hi,

I am not sure if this is a bug or intended. At least I don't understand it:

typedef Foo = {
    x: Int,
    ? y: String,
}

class Test {
    static var a = [{x:1}, {x:2}];
    
    static function test1(): Array<Foo> {
        $type(a); // Test.hx:10: characters 14-15 : Warning : Array<{ x : Int }>
        return a;
    }
    
    static function test2(): Array<Foo> {
    var b = new Array<{x: Int}>();
        $type(b); // Test.hx:16: characters 14-15 : Warning : Array<{ x : Int }>
        b = a;
        return b; // Haxe complains here.
    }
    
    static function main() {
        trace("Haxe is great!");
        var aa = test1();
        trace(aa);
        var bb = test2();
        trace(bb);
    }
}

Test.hx:18: characters 8-16 : Array<{ x : Int }> should be Array<Foo>
Test.hx:18: characters 8-16 : Type parameters are invariant
Test.hx:18: characters 8-16 : { x : Int } should be Foo
Test.hx:18: characters 8-16 : { x : Int } should be { ?y : Null<String>, x : Int }
Test.hx:18: characters 8-16 : { x : Int } has no field y

from what $type tells me both a and b have the same type, why does this not work ? I am quite sure this did work at earlier release.

cheers, Adrian.

JLM

не прочитано,
20 июн. 2016 г., 11:43:3520.06.2016
– Haxe
Adrian
it's quite interesting this compiles which is slightly different, gives lot of different traces on each target
http://try-haxe.mrcdk.com/#bC8cF
I suspect that it's in part that that typedef's disolve into native structures at runtime.  I would suggest you explore how autocasting works with abstract as I suspect it's similar.  But I have no idea if what you posted is correct behaviour.

Adrian Veith

не прочитано,
21 июн. 2016 г., 08:16:0721.06.2016
– Haxe
I guess I was wrong - this didn't compile with earlier versions too. As far as I understand the problem in my example is, that "a" is a monomorph and b in function test2 is fully typed. (why does $type not show a difference?)

What I would need is to return a partially typed monomorph from a macro generated function. The purpose of the macro is to connect to our database server at compile time in order to check the query and to tell the macro which fields and types are returned. This works already like this:

var qy = db.query('table', ['x'], 'x > :x'); // this connects to the database at compile time and checks the query and their types - the field "x" is an Int in "table"
qy.param.x = 12;
var res = qy.results(); // res is typed as List<{x:Int}>
// but this makes problems as in my example
var res2: List<Foo> = qy.results(); // List<{x:Int}> should be List<Foo>...

It would be cool if I could mark qy.results() as a monomorph which could be unified to List<Foo>

Adrian.

JLM

не прочитано,
21 июн. 2016 г., 08:41:3121.06.2016
– Haxe
Adrian

Don't think I can advise beyond you might find that using a class might give you better type reflection than a typedef.

Best

Justin

Adrian Veith

не прочитано,
21 июн. 2016 г., 10:17:1721.06.2016
– Haxe
Hi Justin,

I think classes are not an option, because I want it all happen at compile time. So reflection is not available.

Cheers, Adrian.

Adrian Veith

не прочитано,
23 июн. 2016 г., 23:31:4923.06.2016
– haxe...@googlegroups.com

I guess I was wrong - this didn't compile with earlier versions too. As far as I understand my example is, that "a" is a monomorph and b in function test2 is fully typed.


What I would need is to return a partially typed monomorph from a macro generated function. The purpose of the macro is to connect to our database server at compile time in order to check the query and to tell the macro which fields and types are returned. This works already like this:

var qy = db.query('table', ['x'], 'x > :x'); // this connects to the database at compile time and checks the query and their types - the field "x" is an Int in "table"
qy.param.x = 12;
var res = qy.results(); // res is typed as List<{x:Int}>
// but this makes problems as in my example
var res2: List<Foo> = qy.results(); // List<{x:Int}> should be List<Foo>...

It would be cool if I could mark qy.results() as a monomorph which could be unified to List<Foo>

Adrian.

--
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.

Ответить всем
Отправить сообщение автору
Переслать
0 новых сообщений