I have a struct in which I'd like to create a "parallel" or "auxiliary" type, in order to make use of multiple dispatch, and I was wondering how this could be done... Here is a non-working example with the gist of what I'd like to do:
abstract type ShapeParameter end
abstract type SizeParameter end
struct Example
x :: Real <: ShapeParameter
y :: Real <: SizeParameter
end
Now, I can of course just do:
struct ShapeParameter
shape::Real
end
struct SizeParameter
size::Real
end
struct Example
x ::ShapeParameter
y ::SizeParameter
end
But this solution has the down side that now I cannot just do Example().x
.
And since it's related. I was wondering if it would be possible to similarly create "alternate" types such as PositiveReal
, NegativeReal
and so on. Such that 1.0 <: Real
is true and so is 1.0 <: PositiveReal
.
Would this work for you? Edit: this is wrong :cross_mark:
julia> ShapeParameter = Real
Real
julia> SizeParameter = Real
Real
julia> struct Example
x :: ShapeParameter
y :: SizeParameter
end
julia> ex = Example(4.5, 3.14)
Example(4.5, 3.14)
julia> f(r::Real) = "real arg"
f (generic function with 1 method)
julia> f(s::ShapeParameter) = "shape arg"
f (generic function with 1 method)
julia> f(ex.x)
"shape arg"
You can also use the solution in your post, and fix
But this solution has the down side that now I cannot just do
Example().x
by defining getproperty
and setproperty!
methods for the Example
type that pass the operations through to the underlying Real
value
Sundar R said:
Would this work for you?
julia> ShapeParameter = Real Real julia> SizeParameter = Real Real julia> struct Example x :: ShapeParameter y :: SizeParameter end julia> ex = Example(4.5, 3.14) Example(4.5, 3.14) julia> f(r::Real) = "real arg" f (generic function with 1 method) julia> f(s::ShapeParameter) = "shape arg" f (generic function with 1 method) julia> f(ex.x) "shape arg"
@Sundar R , your example didn't work :(
I mean, it's actually just calling the function that was more recently defined.
Can you expand on the solution with getproperty
?
Davi Sales Barreira said:
Can you expand on the solution with
getproperty
?
julia> import Base: getproperty
julia> function getproperty(ex::Example, sym::Symbol)
if sym == :x
getfield(ex, :x).shape
elseif sym == :y
getfield(ex, :y).size
else
getfield(ex, sym)
end
end
getproperty (generic function with 47 methods)
julia> ex = Example(ShapeParameter(4.5), SizeParameter(3.14))
Example(ShapeParameter(4.5), SizeParameter(3.14))
julia> ex.x
4.5
julia> ex.y
3.14
Thanks!
That's kind of a problematic solution too though, now that I think about it. Any time you access the fields, we're throwing away the type information, so in most circumstances this would be similar to them being just Real
types (for the purpose of dispatch).
It actually worked for my case.
Davi Sales Barreira has marked this topic as resolved.
Last updated: Nov 06 2024 at 04:40 UTC