How can I generalize a custom type call function to an abstract type?

回眸只為那壹抹淺笑 提交于 2019-12-12 11:11:10

问题


I have the following mock setup, with an abstract type, concrete types as subtypes, and a function f which takes two arguments, the first being a Letter.

abstract type Letter end

struct A <: Letter end
struct B <: Letter end

f(::A, x) = ('a', x)
f(::B, x) = ('b', x)

a = A()
b = B()

I would like to define a custom call function for Letter subtypes which simply calls f.

(t::A)(x) = f(t, x)
(t::B)(x) = f(t, x)

While this works, it seems quite redundant, especially considering that there could be many more subtypes of Letter. My attempts are as follows, but neither seem to work.

julia> (t::Letter)(x) = f(t, x)
ERROR: cannot add methods to an abstract type

julia> (t::T)(x) where T <: Letter = f(t, x)
ERROR: function type in method definition is not a type

How can I generalize a call function to match any (concrete) subtype of Letter?


回答1:


Building on Dan's answer, metaprogramming seems to be the way to go

for T in Symbol.(subtypes(Letter))
    @eval (t::$T)(x) = f(t, x)
end

generates functions per type.

Or:

for T in Symbol.(subtypes(Letter))
    c = Char(lowercase(first(String(T))))
    @eval f(::$T, x) = ($c, x)
    @eval (t::$T)(x) = f(t, x)
end

However, this use of structs/subtypes as enums is discouraged



来源:https://stackoverflow.com/questions/44597531/how-can-i-generalize-a-custom-type-call-function-to-an-abstract-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!