The problem arose while I was working with Mods.jl. This package does not support arbitrary-precision arithmetic because only primitive types can be passed as parameters, i.e. Mod{17} works fine, but Mod{big"17"} not.
Due to this I decided to implement something like BigMod with two BigInt fields
struct BigMod <: AbstractMod
value::BigInt
modulus::BigInt
end
Then I had to solve system of linear comparisons, and whilst it worked pretty good for Mod{N} (A \ b with some additional magic) it didn't worked for BigMod at all.
The reason was that LinearAlgebra package uses oneunit function to inference types, but there's no way to define oneunit(::Type{BigMod}), because we don't know modulus in this case (but we do know it for Mod{N}). However this function could be defined for variable of the type BigMod, i.e. oneunit(x::BigMod).
This problem can be solved using Base.return_types inside of LinearAlgebra for type inference, however it seems to be type unstable as well as it returns a collection of possible return types.
I can see only three ways to solve this:
- One day one could use any (at least immutable) types in parameters. In this case no additional code is required, original should be generic enough for everything to work well.
- One day type inference would be improved enough so that no kludges like
typeof(oneunit(eltype(B)) / oneunit(eltype(F)))are needed, one can just sayreturn_type(/, eltype.((B,F)))which is much more generic. - Fight through the pain and rewrite all necessary things from
LinearAlgebraspecially forBigMod
Are there any other ways to reach the goal and what way is the best?