Вызов родительских функторов в Юлии - PullRequest
2 голосов
/ 25 октября 2019

Начиная с версии 1.3 Юлия позволяет отправлять функторы на абстрактные типы . Поэтому мне было интересно, можно ли явно вызвать родительский функтор из дочернего объекта.

Например, в приведенном ниже примере есть ли способ вызвать (x::Foo)() через объект bar::Bar?

abstract type Foo end
(x::Foo)() = "Invoked Foo functor."

struct Bar <: Foo end
(x::Bar)() = "Invoked Bar functor."

bar = Bar()
@info "Calling bar functor directly."
bar() |> println
@info "Invoking parent functor."
# ??? - how to invoke parent functor (x::Foo)() (e.g. desired output "Invoked Foo functor")
invoke(bar,Tuple{Bar}, bar) |> println

1 Ответ

3 голосов
/ 26 октября 2019

как насчет использования 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, предлагающий эту функцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...