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 function foo
which accepts a single 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 only be for example one of the strings "right", "left", or "center"?
In Julia, the motto should be "There's a type for that!". One way of handling this would be to create a type with a constructor that only allows the values you want (and possibly stores them in a more efficient manner). Here is 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, such as :left, :right, and :center, instead of strings. These have the advantage of being interned (so that they can be compared simply by comparing their address), and they can also be used directly for 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))
That will let you do things like: x = MyDirection("left") which will create an immutable object of type MyDirection{:left}.
No, it is not. That would be dispatching on values, which isn't possible in Julia. I'm not sure what your actual application is, but there are some possibly-appropriate workarounds to this, e.g.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With