Functions with 2 generic types

I’m trying to have a function with 2 inputs with different generic types, so I wrote the below:

function mysum(x::T, y::V) where {T, V}
       x+y
end

It worked fine with number, but it accept also Bool inputs, how can I avoid this, and tell ensure the function accept numbers only!

You can add type constraints to your generic types.

function mysum(x::T, y::V) where {T<:Number, V<:Number}
       x+y
end

But in this case the easiest way to write this would simply be

function mysum(x::Number, y::Number)
       x+y
end

both solution still accept boolian s input :frowning:

Oh that’s true, since Boolean<:Number in Julia

julia> 1 + true
2

julia> 1 + false
1

julia> 2.0 * true
2.0

julia> 2.0 * false
0.0

So this is in some sense what you want.

If you really don’t want booleans in your function, you could define a method

mySum(x::Bool, y:: Number) = error("Needs non-booleans!") 
mySum(x::Number, y::Bool) = error("Needs non-booleans!") 

All other numbers will work then.

Actually what I need I is to get an error, not Zero, if any of the 2 inputs is not a number (I mean real number that can be manipulated)

Can you say exactly what sort of numbers you want, then? Should complex numbers be accepted? Booleans are numbers, so why not them? Can you specify?

I mean by numbers any thing from 0123456789 regardless Int, Float,UInt,…

If I want to do this for more than a function it will be a headache; thanks for the try.

But Bool belongs to that set. Could you give a definition of the numbers you want, or is it "anything except Bool"?

A quick (not so elegant) fix, but it works:

julia> function mysum(x::T, y::V) where {T<:Union{Signed, Unsigned, AbstractFloat, AbstractIrrational, Rational}} where {V<:Union{Signed, Unsigned, AbstractFloat, AbstractIrrational, Rational}}
         x + y
       end
mysum (generic function with 1 method)

julia> mysum(2,3)
5

julia> mysum(2,3.2)
5.2

julia> mysum(2,true)
ERROR: MethodError: no method matching mysum(::Int64, ::Bool)
Closest candidates are:
  mysum(::T<:Union{AbstractIrrational, AbstractFloat, Signed, Unsigned, Rational}, ::V<:Union{AbstractIrrational, AbstractFloat, Signed, Unsigned, Rational}) where {V<:Union{AbstractIrrational, AbstractFloat, Signed, Unsigned, Rational}, T<:Union{AbstractIrrational, AbstractFloat, Signed, Unsigned, Rational}} at REPL[13]:2
Stacktrace:
 [1] top-level scope at none:0

Edit: It doesn’t cover all cases though!

I think this one works:

julia> const U = Union{Signed, Unsigned, AbstractFloat, AbstractIrrational, Rational}
Union{AbstractIrrational, AbstractFloat, Signed, Unsigned, Rational}

julia> function mysum(x::T, y::V) where {T<:U,V<:U}
         x + y
       end
mysum (generic function with 1 method)

julia> mysum(2,3)
5

julia> mysum(2,3.2)
5.2

julia> mysum(2.2,3.2)
5.4

julia> mysum(2.2,3)
5.2

julia> mysum(2.2,true)
ERROR: MethodError: no method matching mysum(::Float64, ::Bool)
Closest candidates are:
  mysum(::T<:Union{AbstractIrrational, AbstractFloat, Signed, Unsigned, Rational}, ::V<:Union{AbstractIrrational, AbstractFloat, Signed, Unsigned, Rational}) where {T<:Union{AbstractIrrational, AbstractFloat, Signed, Unsigned, Rational}, V<:Union{AbstractIrrational, AbstractFloat, Signed, Unsigned, Rational}} at REPL[2]:2
Stacktrace:
 [1] top-level scope at none:0

julia> mysum(true,2.2)
ERROR: MethodError: no method matching mysum(::Bool, ::Float64)
Closest candidates are:
  mysum(::T<:Union{AbstractIrrational, AbstractFloat, Signed, Unsigned, Rational}, ::V<:Union{AbstractIrrational, AbstractFloat, Signed, Unsigned, Rational}) where {T<:Union{AbstractIrrational, AbstractFloat, Signed, Unsigned, Rational}, V<:Union{AbstractIrrational, AbstractFloat, Signed, Unsigned, Rational}} at REPL[2]:2
Stacktrace:
 [1] top-level scope at none:0

You can check methods:

julia> methods(mysum)
# 1 method for generic function "mysum":
[1] mysum(x::T, y::V) where {T<:Union{AbstractIrrational, AbstractFloat, Signed, Unsigned, Rational}, V<:Union{AbstractIrrational, AbstractFloat, Signed, Unsigned, Rational}} in Main at REPL[2]:2
2 Likes