Need a little help with parametric types

I want to prepare a example but aren’t able to create it. Can someone help me :slight_smile:

julia> struct ModInt{N <: Integer} <: Integer
           k::Integer
           ModInt{N}(k::Integer) where {N <: Integer} = new(mod(k,N))
       end

julia> ModInt{2}(1)
ERROR: TypeError: in ModInt, in N, expected N<:Integer, got a value of type Int64
Stacktrace:
 [1] top-level scope at REPL[2]:1

Thank you!

You cannot place a type annotation on a field that will be a value/object (2 is a value, not a type).

First consider whether it makes sense to have ModInt have a unique type for each mod that it’s doing (I assume that’s what it’s for). The answer of course is that it makes no sense at all :smiley: and you should just have a second field with the N parameter.

But if this is just an exercise in values-as-parameters, the way to handle this is to remove the type annotation, and use an inner constructor that checks if N is an integer.

1 Like

I want to replicate this example:

That’s a VERY old video. Keep in mind julia 0.3 was out in 2014, and this is year older than even that! I suggest referring to the julia manual as an up to date resource (it features a section on parametric types, of course).

Also note that in the video, there was no type annotation on n. That is, in the definition line, simply: struct ModInt{N} <: Integer was used.

1 Like
julia> struct ModInt{N} <: Integer
           k::Integer
           ModInt{N}(k::Integer) where {N} = new(mod(k,N))
       end

julia> ModInt{2}(1)
ModInt{2}(1)

julia> ModInt{2.1}(1)
ModInt{2.1}(1)

This works but I want to restrict the N to only be Int.

You can do that in the inner constructor:

julia> struct ModInt{N} <: Integer
           k::Integer
           ModInt{N}(k::Integer) where N = N isa Integer ? new(mod(k,N)) : error("helpful error")
       end

By the way, Integer is an abstract type, so code for ModInt will be poorly optimized. Use

k::Int

instead

4 Likes