#=
What if a Union of abstract types were Abstract?
=#
import Base: super, subtypes, typeof # pretend typeof can be overloaded
type AbstractUnion end
super(u::Union) = typejoin(u.types...)
subtypes(u::Union) = [ [(t.abstract ? subtypes(t) : [t]) for t in
u.types]... ]
abstraction(u::Union) = reduce(&, [t.abstract for t in u.types])
typeof(u::Union) = abstraction(u) ? AbstractUnion : Union
# or, Unions get field(s) to include 'abstract'
# or both
typealias SUN Union{Signed,Unsigned}
@assert (typeof(SUN) == AbstractUnion) || (SUN.abstract == (Signed.abstract
& Unsigned.abstract))
abstract MaybeSignedByte <: SUN # would work, super(MaybeSignedByte) could
be super(SUN)
# allowing
type UnsignedByte <: MaybeSignedByte
byte::UInt8
end
type SignedByte <: MaybeSignedByte
byte::Int8
end
# if typeof(byte) is UnsignedByte[SignedByte],
# lsnibble returns an unsigned[signed] value
function lsnibble{T<:MaybeSignedByte}(byte::T)
byte.byte & 0x0F
end
#=
and other good capability (... "the margin is too small" ..)
now, about abstract Unions with parameters
=#
abstract UnitMatrix{T} <: AbstractMatrix{T}
abstract TriangularMatrix{T} <: AbstractMatrix{T}
abstract LowerTriangular{T} <: TriangularMatrix{T}
abstract UpperTriangular{T} <: TriangularMatrix{T}
typealias SpecialTriangular Union{S}{ LowerTriangular{S},
UpperTriangular{S} }
typealias UnitTriangular SpecialTriangular{T}{UnitMatrix{T}}
UnitTriangluar32 = UnitTriangular{Float32}
#=
.. SpecialTriangular{Float32}{UnitMatrix{ T <- Float32 }
.. SpecialTriangular{UnitMatrix{Float32}}
.. Union{UnitMatrix{Float32}}{ LowerTriangular{ S <- UnitMatrix{Float32}
}, .. }
.. Union{ LowerTriangular{UnitMatrix{Float32}},
UpperTriangular{UnitMatrix{Float32}} }
.. abstraction(<above>) == true, so
.. AbstractUnion{ LowerTriangular{UnitMatrix{Float32}},
UpperTriangular{UnitMatrix{Float32}} }
or, (or both)
UnitTriangular32.abstract == true
=#