julia> struct Test <: AbstractFloat
x
end
julia> Base.:^(x::Number, y::Test) = x^(y.x)
# does not work
julia> e^Test(2.0)
ERROR: MethodError: ^(::Irrational{:e}, ::Test) is ambiguous. Candidates:
^(x::Number, y::Test) in Main at REPL[3]:1
^(::Irrational{:e}, x::Number) in Base at irrationals.jl:219
Possible fix, define
^(::Irrational{:e}, ::Test)
That should just work since Irrational <: Number; I would think that there should be an appropriate float conversion fallback.
Actually the real issue here is that what you suggest doesn’t work if you add
struct Test{T <: AbstractFloat} <: AbstractFloat
x::T
end
Base.:^(x::T, y::Test) where {T<:Number} = x^(y.x)
julia> e^Test(2.0)
ERROR: MethodError: ^(::Irrational{:e}, ::Test{Float64}) is ambiguous. Candidates:
^(x::Number, y::Test) in Main at REPL[1]:1
^(::Irrational{:e}, x::Number) in Base at irrationals.jl:219
Possible fix, define
^(::Irrational{:e}, ::Test)
Looks like a peculiarity of e, because it falls back on exp:
julia> struct Test{T<:AbstractFloat} <: AbstractFloat
x::T
end
julia> Base.:^(x::T, y::S) where {T<:Number, S<:Test} = x ^ (y.x)
julia> pi ^ Test(2.0)
9.869604401089358
julia> im ^ Test(2.0)
-1.0 + 0.0im
julia> 5.7 ^ Test(2.0)
32.49
julia> e ^ Test(2.0)
ERROR: not implemented for Test{Float64}
Stacktrace:
[1] ^(::Irrational{:e}, ::Test{Float64}) at ./irrationals.jl:223
julia> exp(Test(2.0))
ERROR: not implemented for Test{Float64}
Stacktrace:
[1] exp(::Test{Float64}) at ./math.jl:275
julia> Base.:^(x::Irrational{:e}, y::S) where {S<:Test} = e ^ (y.x)
julia> e ^ Test(2.0)
7.38905609893065