как насчет использования default
struct?
abstract type Foo end
(x::Foo)() = "Invoked Foo functor."
struct Bar <: Foo end
(x::Bar)() = "Invoked Bar functor."
struct DefaultFoo <: Foo end
#here we dont define an specialized method, DefaultFoo calls Foo
#an interface to define default methods:
default(x::Type{Foo}) = DefaultFoo
function parent(x::T) where {T}
y = default(supertype(T))
return y()
end
наконец, вы можете сделать это для вызова функции по умолчанию:
bar = Bar()
foo = parent(bar)
foo()
это требует определения defaultFoo
тип и default(x::Type{T})
для каждого супертипа. Вы можете автоматизировать это с помощью следующего макроса:
macro create_default_functor(type)
a = gensym(type)
esc(quote
struct $a <: $type end
default(x::Type{$type}) = $a
end)
end
с помощью макроса и вашего кода:
abstract type Foo end
(x::Foo)() = "Invoked Foo functor."
@create_default_functor Foo
struct Bar <: Foo end
(x::Bar)() = "Invoked Bar functor."
function parent(x::T) where {T}
y = default(supertype(T))
return y()
end
#calling bar
bar = Bar()
bar()
#calling foo
foo = parent(bar)
foo()
У меня сейчас нет знаний о макросе, чтобы напрямую вызывать макросна определение абстрактного типа, но это начало. Что касается абстрактных функторов, то это очень новая функция (1.3 еще не выпущена), и, возможно, ее можно добавить в будущие версии julia (что-то вроде call_parent(Foo,args...)
,), если вы добавите PR, предлагающий эту функцию.