Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to distinguish different objects in the same struct using Symbol in Julia?

As mentioned in the title, I want to use multiple-dispatch to assign different behaviors of the same struct, distinguished by Symbol. The struct can be constructed as follows:

struct AbstractAlgorithm
    algorithmName::String
    algorithmSymbol::Symbol

    function AbstractAlgorithm(algorithmName::String)
        if algorithmName ∉ ("Value Iteration", "Policy Iteration")
            error("Given algorithm $algorithmName not defined yet.")
        elseif algorithmName=="Value Iteration"
            new(algorithmName, Symbol("vIter"))
        elseif algorithmName=="Policy Iteration"
            new(algorithmName, Symbol("pIter"))
        end
    end  
end

And I wanted to distinguish the same struct using different symbols in a function, such as:

function A(a::AbstractAlgorithm with Symbol vIter) = do A1
function A(a::AbstractAlgorithm with Symbol pIter) = do A2

How should I design function A using multiple-dispatch?

like image 483
PokeLu Avatar asked Oct 19 '25 09:10

PokeLu


2 Answers

I am adding as an answer a small comment to what @Giovanni proposed since it is too long (+ some minor changes to your code).

If you want to use a parametric type (and not, as @DNF proposed a type hierarchy) you can just write:

struct Algorithm{T}
    algorithmName::String

    function Algorithm(algorithmName::AbstractString)
        algorithmName == "Value Iteration" && return new{:vIter}(algorithmName)
        algorithmName == "Policy Iteration" && return new{:pIter}(algorithmName)
        error("Given algorithm $algorithmName not defined yet.")
    end
end

function A(a::Algorithm{:pIter})
    # ...
end

function A(a::Algorithm{:vIter})
    # ...
end

The point is that Symbol can be used as type parameter, so you do not have to wrap it in Val.

like image 129
Bogumił Kamiński Avatar answered Oct 20 '25 22:10

Bogumił Kamiński


This seems like a highly unusual and un-idiomatic approach, since Julia natively supports multiple dispatch. Also, AbstractNN is a naming convention for abstract types, while you are using it for a concrete type.

Why not instead use dispatch:

abstract type AbstractAlgorithm end

struct ValueIteration <: AbstractAlgorithm end

struct PolicyIteration <: AbstractAlgorithm end

and then implement your wanted behaviors based on the types of your algorithm objects:

A(::ValueIteration) = A1() 
A(::PolicyIteration) = A2() 
like image 36
DNF Avatar answered Oct 20 '25 21:10

DNF