Type alias interferes with construction

Why does construction using the type alias for Hyperplane result in an error?

using FastClosures, GLMakie, Random, Distributions, Parameters, Rotations, StaticArrays, LinearAlgebra, CoordinateTransformations, Makie, Meshes, Unitful

const VectorNd{N} = SVector{N,Float64} 
const Vector2d = VectorNd{2}
const Vector3d = VectorNd{3}

homogenize(x::Union{SVector, Meshes.Vec}) = push(x,one(eltype(x)))

struct Hyperplane{N} <: StaticVector{N, Float64}
    v::VectorNd{N}
    Hyperplane(v::VectorNd{N}) where N = new{N}(v / norm(v[1:N-1]))
end

@inline Base.getindex(p::Hyperplane, i::Int) = getindex(p.v, i)
@inline Tuple(p::Hyperplane) = Tuple(p.v)

const Line2 = Hyperplane{3}
Line2(SVector{3}(1.,2.,4.))

results in

ERROR: DimensionMismatch: No precise constructor for Line2 found. Length of input was 3.
Stacktrace:
[1] _no_precise_size(SA::Type, x::Tuple{Float64, Float64, Float64})
@ StaticArrays ~/.julia/packages/StaticArrays/MSJcA/src/convert.jl:169
[2] construct_type(::Type{Line2}, x::StaticArrays.Args{Tuple{Tuple{Tuple{Float64, Float64, Float64}}}})
@ StaticArrays ~/.julia/packages/StaticArrays/MSJcA/src/convert.jl:89
[3] StaticArray (repeats 2 times)
@ ~/.julia/packages/StaticArrays/MSJcA/src/convert.jl:173 [inlined]
[4] Line2(sa::SVector{3, Float64})
@ StaticArrays ~/.julia/packages/StaticArrays/MSJcA/src/convert.jl:180
[5] top-level scope
@ REPL[11]:1

Clearly I am missing something about the type system. Thank you.

This isn’t related to the presence of Line2, or to the type system. You’ll get the same error by just writing Hyperplane{3} directly instead of Line2.

I’m not knowledgeable enough about the StaticArrays.jl interface that you’re implementing, but clearly either:

  • you’re not implementing their interface correctly
  • there’s a bug in StaticArrays.jl (less likely, I guess)
  • you meant to add more constructors for your struct

Yes, I see that. I don’t understand why the error occurs, though. I don’t think any constructors are missing.

Did not run the code, but i think that error occurs, because you don’t have a constructor for Hyperplane that explicitly takes the type parameter, but only one where the parameter is deduced from the argument, no?

So defining that (although it seems redundant at first) should fix the issue.

EDIT:
Basically, adding the following

Hyperplane{N}(v::VectorNd{N}) where N = Hyperplane(v)

Yes, that works… thank you! It does seem redundant. I’ll have to think about why it is required.

You define a constructor for HyperPlane above, not for HyperPlane{3}. The two clearly aren’t equal. Perhaps this section in the docs might be of use: Constructors are just callable objects