-
Notifications
You must be signed in to change notification settings - Fork 4
Description
I think it's common enough in generic programming that one works with different layers of objects. For example some iterator of objects, where the iterator could be an array, a tuple, etc. and the object anything that serves some further purpose. That further purpose could again be locked down by an interface I thought. Here I jotted down some code where I made a ReturnInterface that should guarantee a given signature returns an object that conforms to a given interface (that interface can simply be that it should be a certain type, or whatever more complex thing).
I also had the idea of splitting run time and compile time traits and only allowing composition of compile time traits into new compile time traits, but I haven't followed that here. Just including it for inspiration. I bet that relying on _return_type has all sorts of problems, I already hit some uninferred cases during casual testing. But it seems like the only thing we got after all?
abstract type Interface end
abstract type CompileTimeInterface <: Interface end
abstract type RunTimeInterface <: Interface end
abstract type CompositeInterface <: Interface end
struct AndInterface{T<:Tuple} <: CompositeInterface
interfaces::T
end
test_implements(x, a::AndInterface) = all(i -> test_implements(x, i), a.interfaces)
struct OrInterface{T<:Tuple} <: CompositeInterface
interfaces::T
end
test_implements(x, a::AndInterface) = any(i -> test_implements(x, i), a.interfaces)
struct HasMethodInterface{SIG} <: CompileTimeInterface
signature::SIG
end
test_implements(x, m::HasMethodInterface) = hasmethod(x, m.signature)
struct TypeInterface3{T<:Type} <: CompileTimeInterface
type::T
end
test_implements(x, t::TypeInterface3) = x <: t.type
struct ReturnInterface{SIG,I<:Interface} <: CompileTimeInterface
signature::SIG
returninterface::I
end
function test_implements(x, r::ReturnInterface)
ret = Base._return_type(x, r.signature)
ret === Base.Bottom && return false
test_implements(ret, r.returninterface)
end