Type unions

In geometry, a two-dimensional point and a vector are not the same, even if they both have an x and y component. In Julia, we can also define them as different types, as follows:

# see the code in Chapter 6unions.jl
mutable struct Point
x::Float64
y::Float64
end

mutable struct Vector2D
x::Float64
y::Float64
end

Here are the two objects:

  • p = Point(2, 5) that returns Point(2.0, 5.0)

  • v = Vector2D(3, 2) that returns Vector2D(3.0, 2.0)

Suppose we want to define the sum for these types as a point which has coordinates as the sum of the corresponding coordinates:

+(p, v)

This results in an ERROR: MethodError: `+` has no method matching +(::Point, ::Vector2D) error message.

To define a + method here, first do an import Base.+

Even after defining the following, +(p, v) still returns the same error because of multiple dispatch. Julia has no way of knowing that +(p,v) should be the same as +(v,p):

+(p::Point, q::Point) = Point(p.x + q.x, p.y + q.y)
+(u::Vector2D, v::Vector2D) = Point(u.x + v.x, u.y + v.y)
+(u::Vector2D, p::Point) = Point(u.x + p.x, u.y + p.y)

Only when we define the type matching method as +(p::Point, v::Vector2D) = Point(p.x + v.x, p.y + v.y), do we get a result +(p, v), which returns Point(5.0,7.0).

Now you can ask the question: Don't multiple dispatch and many types give rise to code duplication, as is the case here?

The answer is no, because, in such a case, we can define a union type, VecOrPoint:

VecOrPoint = Union{Vector2D, Point}

If p is a point, it is also of type VecOrPoint, and the same is true for v which is Vector2D. isa(p, VecOrPoint) and isa(v, VecOrPoint); both return true.

Now we can define one + method that works for any of the preceding four cases:

+(u::VecOrPoint, v:: VecOrPoint) = VecOrPoint(u.x + v.x, u.y +
v.y)

So, now we only need one method instead of four.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.134.130