Intersection types
Note: This section is a stub.
Intersection types allow you to define multiple signatures for a single function, similar to function or method overloading in languages such as Java, C# and C++. Unlike the previous languages, Alore functions always have a single body.
Intersection type basics
Specify an intersection type using the or keyword after a normal function signature, followed by another signature without the function name. This examples defines a function that can be called with either a Str or Int argument:
def IncStr(x as Str) as Str or (x as Int) as Str if x is Str return Str(Int(x) + 1) else return Str((x as Int) + 1) end end IncStr('6') -- '7' IncStr(5) -- '6'
There a several things to note:
- The body of the function must type check for all signatures (both when x is Str and when x is Int). This is why we need the x as Int cast in the else block.
- We use a runtime type check (if x is Str) to determine the actual type of the argument. In some functions with intersection types this is not necessary, but often it is.
- The behavior of the function remains the same after type erasure (see also Running programs with mixed typing).
- If the different signatures in an intersection type have different return value types, you may have to cast the return values to dynamic to avoid type check errors.
Alore standard libraries use intersection types in several places, most notably for arithmetic operators such as +. They allow the following code to type check:
2 * 3 -- Int * Int 2 * 1.1 -- Int * Float 2 * 'x' -- Int * Str
Overlapping signatures
Signatures in intersection types must not be overlapping, unless they have identical return value types. Consider this example:
def f(x as Int) as Int (x as Object) as Str ... end
When called with an Int argument, either of the signatures can match; they are overlapping. This would not be a problem if the return value types would be identical, but they are different (Int and Str).
Interface methods and intersection types
If a class implements two interfaces with an identically-named method, you may be able to define an intersection type for the method that is compatible with both the interfaces.