Hi
min<T:Int & Float>
means that the type has to be compatible with both Int AND Float, which is not what you want in this case as Int and Float are not fully compatible with each other.
Probably there are more elegant and robust ways to achieve what you want, but this solution works as expected.
First I created an Abstract of which the underlying type’s values can be compared (Int, Float, and I threw in String as well just to make the example more understandable) by exposing the required type operations.
abstract Comparable(Dynamic) from Int to Int from Float to Float from String to String {
@:op( A < B )
static public function lt<T>( a:Comparable, b:Comparable ):Bool;
@:op( A > B )
static public function gt<T>( a:Comparable, b:Comparable ):Bool;
}
Then I used this Comparable
abstract type as the type parameter in the static extension’s min()
function:
class ArrayExtensions {
static public function min<T:Comparable>( arr:Array<Comparable> ):Comparable {
var minValue = arr[0];
// Notice the zero-indexing!
for (i in 0...arr.length) {
if (arr[i] < minValue) {
minValue = arr[i];
}
}
return minValue;
}
}
Fully working example code:
package;
import haxe.Json;
using Main.ArrayExtensions;
class Main {
static public function main() {
var intA:Comparable = 123;
var intB:Comparable = 456;
trace( '$intA is smaller than $intB: ${intA < intB}' );
trace( '$intA is larger than $intB: ${intA > intB}' );
var floatA:Comparable = 123.456;
var floatB:Comparable = 789.012;
trace( '$floatA is smaller than $floatB: ${floatA < floatB}' );
trace( '$floatA is larger than $floatB: ${floatA > floatB}' );
var stringA:Comparable = 'Hello';
var stringB:Comparable = 'World';
trace( '$stringA is smaller than $stringB: ${stringA < stringB}' );
trace( '$stringA is larger than $stringB: ${stringA > stringB}' );
// These won't compile as they are of unsupported types
// var arrayA:Comparable = [];
// var boolA:Comparable = false;
var comparableArrayA:Array<Comparable> = [ 5, 2, -3, 4 ];
trace( 'ArrayExtensions.min() of comparableArrayA is: ${comparableArrayA.min()}' );
trace( 'comparableArrayA as JSON: ${Json.stringify( comparableArrayA )}' );
var comparableArrayB:Array<Comparable> = [ 5.5, 2.2, -33.3, -44.004 ];
trace( 'ArrayExtensions.min() of comparableArrayB is: ${comparableArrayB.min()}' );
trace( 'comparableArrayB as JSON: ${Json.stringify( comparableArrayB )}' );
var comparableArrayC:Array<Comparable> = [ 1, 9.99, 'hello' ];
trace( 'ArrayExtensions.min() of comparableArrayC is: ${comparableArrayC.min()}' );
trace( 'comparableArrayC as JSON: ${Json.stringify( comparableArrayC )}' );
// Using ArrayExtensions.min() as static extension
var value = [5, 2, -3, 4].min();
trace( 'Smallest value is: ${value}' );
var value = [5.1, 2.2, -3.3, 4.5].min();
trace( 'Smallest value is: ${value}' );
var value = [ "quick", "brown", "fox" ].min();
trace( 'Smallest value is: ${value}' );
// Won't compile
// var value = [ true, false ].min();
// trace( 'Smallest value is: ${value}' );
}
}
abstract Comparable(Dynamic) from Int to Int from Float to Float from String to String {
@:op( A < B )
static public function lt<T>( a:Comparable, b:Comparable ):Bool;
@:op( A > B )
static public function gt<T>( a:Comparable, b:Comparable ):Bool;
}
class ArrayExtensions {
static public function min<T:Comparable>( arr:Array<Comparable> ):Comparable {
var minValue = arr[0];
// Notice the zero-indexing!
for (i in 0...arr.length) {
if (arr[i] < minValue) {
minValue = arr[i];
}
}
return minValue;
}
}
Output:
Main.hx:12: 123 is smaller than 456: true
Main.hx:13: 123 is larger than 456: false
Main.hx:17: 123.456 is smaller than 789.012: true
Main.hx:18: 123.456 is larger than 789.012: false
Main.hx:22: Hello is smaller than World: true
Main.hx:23: Hello is larger than World: false
Main.hx:31: ArrayExtensions.min() of comparableArrayA is: -3
Main.hx:32: comparableArrayA as JSON: [5,2,-3,4]
Main.hx:35: ArrayExtensions.min() of comparableArrayB is: -44.004
Main.hx:36: comparableArrayB as JSON: [5.5,2.2,-33.3,-44.004]
Main.hx:39: ArrayExtensions.min() of comparableArrayC is: 1
Main.hx:40: comparableArrayC as JSON: [1,9.99,"hello"]
Main.hx:44: Smallest value is: -3
Main.hx:47: Smallest value is: -3.3
Main.hx:50: Smallest value is: brown