hello, coming across StatsBase.AbstractWeights, I found it could enforce fields to be inherited. e.g.
import StatsBase
struct MyWeights1{S<:Real, T<:Real, V<:AbstractVector{T}} <: StatsBase.AbstractWeights{S, T, V}
values::V
sum::S
end
struct MyWeights2{S<:Real, T<:Real, V<:AbstractVector{T}} <: StatsBase.AbstractWeights{S, T, V}
notvalues::V
notsum::S
end
x = MyWeights1([1.0, 2.0], 3.0)
y = MyWeights2([1.0, 2.0], 3.0)
julia> x = MyWeights1([1.0, 2.0], 3.0)
2-element MyWeights1{Float64,Float64,Array{Float64,1}}:
1.0
2.0
julia> y = MyWeights2([1.0, 2.0], 3.0)
Error showing value of type MyWeights2{Float64,Float64,Array{Float64,1}}:
ERROR: type MyWeights2 has no field values
I tried to go thru the code, but not understand how could it be done
could someone be nice enough to explain the trick? thanks.
I don’t know the code but I assume that it just requires those fields to be defined for the methods to work. Have a look at show method which threw above error: @less show(stdout, MyWeights2([1.0, 2.0], 3.0)). I suspect it is defined on the AbstractWeights and accesses .value.
Yes, that works. But presumably other functionality of StatsBase doesn’t work either with those fields. It should be described in the docs, what needs to be satisfied to hook into the functionality of StatsBase.
There is no trick. As @mauro3 explained, some code just assumes that when typeof(x) <: AbstractWeights, it has certain fields implemented.
It is not clear that StatsBase.AbstractWeights was meant to be extended outside the package. However, if you want to do this, and implement it with different fields, you should just implement the interface, which is probably something like this.