Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force integral type parameter in Julia

Tags:

types

julia

I would like to define a simple type to represent an n-dimensional shape, with a type parameter containing n.

julia> struct Shape{n}
           name::String
       end

julia> square = Shape{2}("square")
Shape{2}("square")

julia> cube = Shape{3}("cube")
Shape{3}("cube")

julia> dim(::Shape{n}) where n = n
dim (generic function with 1 method)

julia> dim(cube)
3

While this solution does work, it accepts non-integral values of n with no issues.

julia> Shape{'?'}("invalid")
Shape{'?'}("invalid")

My initial thought was to use a constraint on n in the struct declaration. However, neither of the ways I thought this should be accomplished seemed to work.

julia> struct Shape{n} where n <: Int
           name::String
       end
ERROR: syntax: invalid type signature

julia> struct Shape{n<:Int}
           name::String
       end

julia> Shape{2}("circle")
ERROR: TypeError: Shape: in n, expected n<:Int64, got Int64

I also tried using an inner constructor, but this did not seem to work either.

julia> struct Shape{n}
           Shape{n}(name) where n <: Int = new(name)
           name::String
       end

julia> Shape{2}("circle")
ERROR: MethodError: Cannot `convert` an object of type String to an object of type Shape{2}
This may have arisen from a call to the constructor Shape{2}(...),
since type constructors fall back to convert methods.
Stacktrace:
 [1] Shape{2}(::String) at ./sysimg.jl:24

I am using Julia 0.6.0-rc3.0.

How can I achieve the desired behavior?

like image 438
Harrison Grodin Avatar asked Mar 09 '23 21:03

Harrison Grodin


1 Answers

The type of n is an Int, but it is not a DataType which is <:Int. You need to let it where n and then @assert typeof(n) <: Int inside the constructor.

 struct Shape{n}
   name::String
   function Shape{n}(name) where n 
     @assert typeof(n) <: Int
     new(name)
   end
 end
 Shape{2}("square")
 Shape{:hi}("square")
like image 160
Chris Rackauckas Avatar answered Mar 18 '23 05:03

Chris Rackauckas