In Java, suppose I have a method that takes in two lists of integers, and returns an arrayList of integers from the first list, based upon the second list.
public ArrayList<Integer> func(ArrayList<Integer> A, ArrayList<Integer> B){
ArrayList result = new ArrayList();
//A and B have the same length
for(int index = 0; index < A.length();index++){
//Decide if a gets added to result based on the corresponding B
if(decisionFunction(B.get(i)){
result.add(a.get(i));
}
}
return result;
}
Now suppose I did something silly like change the insertion to
result.add(b.get(i));
It’d be nice if I could do something like
public ArrayList<AInteger> func(ArrayList<AInteger> A, ArrayList<BInteger> B)
to ensure that regardless of sleep deprivation, the compiler would prevent me from making this type of mistake. Now we could try
class AInteger extends Integer{}; class BInteger extends BInteger{};
and call the method with
func((ArrayList<AInteger>) A, (ArrayList<BInteger>) B);
Unfortunately, downcasting will raise a runtime exception. So, this solution would require me (I think) to rebuild A and B into new Lists with the appropriate datatype, which is expensive. Aside from being more careful, and using unit tests, is there anyway to get the compiler to distinguish between the two lists?
Do other languages such as Scala, or Haskell, provide something that allows me to recast safely without copying?
By using generics, this can be solved by modifying the function declaration to be
This ensures that
result.add(B.get(i))raises a type error as desired.Unfortunately… new IntegerA(int) is not allowed, which prevents new objects from being created. So resulting exported list can only contain elements from the original list (unless downcasting is performed, which nullifies any type guarantees).