How to Create new method signature on union of types

First we create a composite type AffineExpression using struct

struct AffineExpression
    variables::Vector{Variable}
    coeffs::Vector{Float64}
    constant::Float64
end

Then we define the expression “+” as AffineExpression

import Base: +
+(x::Real,y::Union{Real,Variable}) = AffineExpression([y],[x],0.0)

So “x+2” can be taken as an affine expression

But how to define “+” then if one input has several types in the form of union?

+(x::Variable,y::Union{Real,Variable,AffineExpression}) = 

I think I can make it separately without union, repeat each case of y as Real, Variable, AffineExpression

However, I guess using union will provide a more elegant approach.

Any hint will be much appreciated!!!

Overriding a method defined outside your module for types not defined in your module is generally a bad idea.
That +(::Real, ::Real) returns a real number, not AffineExpression, is probably relied upon in more than one place inside Base, so that I very much suspect the effect of such override would be disastrous.
Now, on the question (because it still makes sense when not coupled with a careless override). One way is repeat each case, another one is to define promotions from all those types to AffineExpression and then basically only define +(::AffineExpression, ::AffineExpression) (cf. https://github.com/jmxpearson/julia-for-pythonistas/blob/master/dual.jl)

1 Like

Thank you Vasily! Yes you are right that I am actually working within a new module. As you mentioned, [quote=“Vasily_Pisarev, post:2, topic:30375”]
define promotions from all those types to AffineExpression and then basically only define +(::AffineExpression, ::AffineExpression)
[/quote]
I define a convert function to get

::Real and ::Variable to AffineExpression and it works as expected, promote seems error though.

You need both promotion and conversion rules.
promote is to define what common type two arguments of a built-in mathematical function must be converted to, convert is to define how exactly to do that.

1 Like