@internal class Array[T](len: Int) { @internal fun length() -> Int; @internal fun get(idx: Int) -> T; @internal fun set(idx: Int, val: T); } // The next two functions should be instance functions, but we cannot properly encode the fact that they put additional // constraints on the existing class-level `T` of `Array`, not introduce a new function-level `T` on `contains`: // fun contains[T : Identity + Equals](value: T) -> Bool /// wrong // Some languages use the workaround to define a "fake" new generic parameter that subtypes the old one, like // `[S <: T : Identity + Equals]`. I hope that a better solution can be found. fun arrayContains[T : Identity + Equals](array: Array[T], value: T) -> Bool { var i = 0; while i < array.length() { let x = array.get(i); if x.identicalTo(value) || x.equals(value) { return true; } i = i + 1; } return false; } fun arrayHas[T : Identity](array: Array[T], value: T) -> Bool { var i = 0; while i < array.length() { if array.get(i).identicalTo(value) { return true; } i = i + 1; } return false; } fun arrayEmpty[T]() -> Array[T] = Array[T](0); fun arrayFill[T](len: Int, value: T) -> Array[T] { let array = Array[T](len); var i = 0; while i < len { array.set(i, value); i = i + 1; } return array; } fun arrayNew[T: Default](len: Int) -> Array[T] { let array = Array[T](len); var i = 0; let value = T::default(); while i < len { array.set(i, value); i = i + 1; } return array; } fun arrayCopy[T](src: Array[T], srcPos: Int, dest: Array[T], destPos: Int, len: Int) { var i = 0; while i < len { dest.set(destPos+i, src.get(srcPos+i)); i = i + 1; } }