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"?
source to share
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}.
source to share
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)
source to share