Let's now summarize all the options that we have considered so far:
Option | Signature | Passed all tests? |
1 | sumprod(A::Vector{Float64}, B::Vector{Float64}) | No |
2 | sumprod(A::Vector{Number}, B::Vector{Number}) | No |
3 | sumprod(A::Vector{T}, B::Vector{T}) where T <: Number | No |
4 | sumprod(A::Vector{S}, B::Vector{T}) where {S <: Number, T <: Number} | No |
5 | sumprod(A::Array{S,N}, B::Array{T,N}) where {N, S <: Number, T <: Number} | Yes |
6 | sumprod(A::AbstractArray{S,N}, B::AbstractArray{T,N}) where {N, S <: Number, T <: Number} | Yes |
7 | sumprod(A, B) | Yes |
Technically speaking, options 5, 6, or 7 could work for all array types. Options 6 and 7 support other array containers, such as sparse matrix. Option 7 works with non-AbstractArray types, as long as the type is broadcasting multiplication as well as summation.
Before we draw our conclusion, let's do one last test from a performance perspective. Do you wonder whether making the function accept more general types would sacrifice performance? The only way to know this is to prove it with real experiments. Let's do that next.