# 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!

``````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

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