This simple GaloisField type is parameterized by the modulus p
and the integer type T
. It works fine, but note that the test on the type of p
buried within an inner constructor.
using Primes
# Type definition: GaloisField{p,T}, where p is prime modulus, T is integer type
struct GaloisField{p,T} <: Number where {p, T<:Integer}
rep::T # representative integer
# inner constructor
function GaloisField{p,T}(x::Integer) where {p, T<:Integer}
if !(typeof(p) <: Integer) || !isprime(p)
throw(ArgumentError("p must be a prime integer"))
end
return new(mod(x, p))
end
end
GaloisField{p}(x::T) where {p,T<:Integer} = GaloisField{p,T}(x)
It would seem better to require that p
be an integer in the type signature, like this
using Primes
# Type definition: GaloisField{p,T}, where p is prime modulus, T is integer type
struct GaloisField{p,T} <: Number where {p::Integer, T<:Integer}
rep::T # representative integer
# inner constructor
function GaloisField{p,T}(x::Integer) where {p::Integer, T<:Integer}
if !isprime(p)
throw(ArgumentError("p must be a prime"))
end
return new(mod(x, p))
end
end
GaloisField{p}(x::T) where {p::Integer,T<:Integer} = GaloisField{p,T}(x)
but that gives the error
syntax: invalid variable expression in "where" around In[2]:4
Stacktrace:
[1] top-level scope
@ In[2]:4
[2] eval
@ ./boot.jl:360 [inlined]
[3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
@ Base ./loading.jl:1094
Wouldn’t this be better? Why doesn’t it work?
And what’s with the syntax const T2 = Array{Array{T, 1}, 1} where T
(from the UnionAll section of the Types in Julia Docs)? Am I supposed to read that as ...where T<:Any
? To me an unadorned where T
is like an unfinished sentence.
The GaloisField code is an update of an example from a 2016ish talk by Andreas Noack.