# How to Create new method signature on union of types

**URL:** <https://discourse.julialang.org/t/how-to-create-new-method-signature-on-union-of-types/30375>\
**Category:** General Usage\
**Tags:** question\
**Created:** [October 27, 2019, 8:43pm UTC](https://discourse.julialang.org/t/how-to-create-new-method-signature-on-union-of-types/30375 "2019-10-27T20:43:33Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Fisheryu1234](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fisheryu1234/32/9588_2.png) [@Fisheryu1234](https://discourse.julialang.org/u/Fisheryu1234)\
**Post date:** [October 27, 2019, 8:43pm UTC](https://discourse.julialang.org/t/how-to-create-new-method-signature-on-union-of-types/30375/1 "2019-10-27T20:43:33Z")

</div>

First we create a composite type **AffineExpression** using struct

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

```

Then we define the expression “+” as **AffineExpression**

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

```julia
+(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!!!

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [October 27, 2019, 9:40pm UTC](https://discourse.julialang.org/t/how-to-create-new-method-signature-on-union-of-types/30375/2 "2019-10-27T21:40:03Z")

</div>

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](https://github.com/jmxpearson/julia-for-pythonistas/blob/master/dual.jl))

---

<div class="post-metadata">

**Author:** ![Fisheryu1234](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fisheryu1234/32/9588_2.png) [@Fisheryu1234](https://discourse.julialang.org/u/Fisheryu1234)\
**Post date:** [November 1, 2019, 5:29am UTC](https://discourse.julialang.org/t/how-to-create-new-method-signature-on-union-of-types/30375/3 "2019-11-01T05:29:18Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [November 1, 2019, 8:14am UTC](https://discourse.julialang.org/t/how-to-create-new-method-signature-on-union-of-types/30375/4 "2019-11-01T08:14:46Z")

</div>

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.
