Sum types as sealed abstract types

In the various discussions about sum types in Julia, I don’t recall seeing any discussion of how sum types would interact with the existing type system. So, here’s one idea that comes to mind:

Perhaps a sum type could be represented by a sealed abstract type, similar to sealed classes in Java, Scala, and Kotlin. A sealed abstract type would be an abstract type with a fixed list of subtypes that cannot be extended. Aside from being sealed, sealed abstract types would behave exactly the same as regular abstract types.

We already have a good amount of pattern matching via dispatch and argument destructuring, so using a sealed abstract type as a sum type could look something like this:

sealed abstract type Shape begin
    struct Rectangle
        w::Float64
        h::Float64
    end

    struct Square
        w::Float64
    end

    struct Triangle
        b::Float64
        h::Float64
    end
end

area((; w, h)::Rectangle) = w * h
area((; w)::Square) = w * w
area((; b, h)::Rectangle) = b * h / 2

This is almost identical Moshi.Data.@data types in Moshi.jl, including the pattern matching using Moshi.Match.@match. Is there something different I’m not catching?

I think the main difference is that each struct is its own standalone type, but in Moshi you implement the overarching type as a union, which solves problems of e.g. getting performant inferred supertypes for collections.

using Moshi.Data: @data
using Moshi.Match: @match

@data Shape begin
    struct Rectangle
        w::Float64
        h::Float64
    end

    struct Square
        w::Float64
    end

    struct Triangle
        b::Float64
        h::Float64
    end
end

area(shape::Shape.Type) = @match shape begin
    Shape.Rectangle(; w, h) => w * h
    Shape.Square(; w) = w * w
    Shape.Triangle(; b, h) = b * h / 2
end