#=
    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
=#


Reply via email to