Closed mockey closed 5 years ago
Uhm, did we ever allow String < String
?
static function sortAsc<T>(arr:Array<T>):Array<T> {
arr.sort(Reflect.compare);
return arr;
}
@Simn yes, strings can be freely compared, I think (and mostly hope) it's part of our std unit tests
Reflect.compare
was completely new to me, live and learn, thanks for that.
And it still compiles with current version :-)
I think I've written that compare/sort function a hundred times or so...
But about my other question: Is a constraint for two types possible, like String or Int?
BTW: Is that compile error actually an issue then?
Does it even make sense to have a constraint like that? The only type you will be able to pass there is String
.
Yes, that doesn't make sense. I was only playing around with that constraint, because <T>
didn't compile when T
was a String
. It seems that the compiler only allows Int
or Float
to be compared with <
/ >
. Reflect.compare
seems to bypass that somehow, though, it compiles with <T>
.
The original idea was to have a function that can sort arrays of String
or Int
(because for other types the compare function probably won't work or throw an error). So a constraint like <T:Int | String>
might be nice. Or should <T:EitherType<Int,String>>
be used then?
Hmm, the easiest way is to use static extensions:
//ArrayTools.hx
class NumericArrayTools {
static public function sorted<T:Float>(a:Array<T>) {
arr.sort((v1, v2) -> v1 > v2 ? 1 : (v1 < v2 ? -1 : 0));
return arr;
}
}
class StringArrayTools {
static public function sorted(a:Array<String>) {
arr.sort((v1, v2) -> v1 > v2 ? 1 : (v1 < v2 ? -1 : 0));
return arr;
}
}
And then using ArrayTools;
you can just do someArray.sorted()
if it's Int
/Float
/String
.
Alternatively, there's a way to abuse the type system so that it accepts this:
class Test {
static function main() {
var a:Array<Int> = [];
sort(a);
}
static function sort<T:Sortable>(arr:Array<T>) {
arr.sort((v1:Sortable, v2:Sortable) -> v1 > v2 ? 1 : (v1 < v2 ? -1 : 0));
return arr;
}
}
@:coreType abstract Sortable from Float from Int from String {
@:op(a > b) static function gt(a:Sortable, b:Sortable):Bool;
@:op(a < b) static function lt(a:Sortable, b:Sortable):Bool;
@:op(a >= b) static function gte(a:Sortable, b:Sortable):Bool;
@:op(a <= b) static function lte(a:Sortable, b:Sortable):Bool;
}
As a side note: the code doesn't compile without explicitly typing the arguments as Sortable
. Perhaps it should?
This used to work:
But in current git version I get the compile error:
Cannot compare sortAsc.T and sortAsc.T
I understand that not every T is comparable like this, but I get the same error forsortAsc<T:String>
, whilesortAsc<T:Int>
works. Is that correct?Actually I would like to have that function for Int or String. Is there a syntax for that? I only saw
<T:Int & String>
but there is no<T:Int | String>
, is there? Would<T:EitherType<Int,String>>
work?