The constrain argument must be in the set of values ​​in the Julia function signature

Is there a way in Julia to specify that a function argument can take one of a set of values ​​through type annotations? For example, let's say I have a function foo

that takes one argument

function foo(x::String)
    print(x)
end

      

the argument x

can only be a string. Is there a way to further constrain it in the function signature so that it can be, for example, just one of the lines "right", "left", or "center"?

+3


source to share


2 answers


In Julia, the motto should be "There's a guy for that!" One way to handle this would be to create a type with a constructor that only allows the values ​​you want (and maybe store them in a more efficient way). Here's one example:

const directions = ["left", "right", "center"]
immutable MyDirection
    Direction::Int8
    function MyDirection(str::AbstractString)
        i = findnext(directions, str, 1)
        i == 0 && throw(ArgumentError("Invalid direction string"))
        return new(i)
    end
end

Base.show(io::IO, x::MyDirection) = print(io, string("MyDirection(\"",directions[x.Direction],"\")"))
function foo(x::MyDirection)
    println(x)
end

function foo(str::AbstractString)
    x = MyDirection(str)
    println(x)
end

test = MyDirection("left")

foo(test)

foo("right")

      

Note: my example is written with Julia 0.4!

Edit: Another approach would be to use symbols like: left,: right and: center instead of strings. They have the advantage that they are interned (so that they can be compared simply by comparing their address), and they can also be used directly on type parameters.



For example:

immutable MyDirection{Symbol} ; end
function MyDirection(dir::Symbol)
    dir in (:left, :right, :center) || error("invalid direction")
    MyDirection{dir}()
end
MyDirection(dir::AbstractString) = MyDirection(symbol(dir))

      

This will allow you to do things like: x = MyDirection ("left") which will create an immutable object of type MyDirection {: left}.

+5


source


No, it is not. This will send valuables, which is not possible in Julia. I'm not sure what your actual application is, but there are some possible suitable workarounds for this, eg.



abstract Sam81Args
type ArgRight <:Sam81Args end
type ArgLeft <:Sam81Args end
type ArgCenter <:Sam81Args end
function foo{T<:Sam81Args}(x::Type{T})
    println(T)
end
foo(ArgCenter)

      

+1


source







All Articles