-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve return type of isPrimitiveRoot' #154
Comments
I strongly agree. A large part of this issue is that |
As a palliative measure we may add a semantic equivalent of arePrimitiveRoots :: (Functor f, KnownNat n) => f (Mod n) -> f (Maybe (PrimitiveRoot n))
arePrimitiveRoots = undefined It seems that a proper solution should include promoting factorisation of modulo to the type level. In this case we can both ensure type safety (that |
This sounds like a reasonable temporary fix. In experimenting for #119 I tried modulo factorisation on the type-level, and it came out fairly unwieldy and impractical: as far as I can tell, we would effectively need a type-level proof of the fundamental theorem. |
Sounds like a challenge :) |
I've sketched a possible new type structure to fix this in #158, but it would be a breaking change if it fully replaces the existing CyclicGroup. Also, the structure I describe is restricted to Natural, but I do not think this is much of a restriction. |
I am fine with breaking changes here. |
In that case, shall I continue with the PR and propagate the change through tests and benchmarks, replacing the existing structures? |
Yes, please proceed. I am not totally convinced in design of Hmm, data Foo (m :: Nat) = Foo [(Prime Natural, Word)] where the term-level list is a factorisation of a type-level integer. It looks like a way to achieve both type safety and avoid repetitive factorisations in solveQuadratic :: KnownNat m => Mod m -> Mod m -> Mod m -> [Mod m] which is vastly inefficient in loops like solveQuadratic' :: KnownNat m => Foo m -> Mod m -> Mod m -> Mod m -> [Mod m] |
I'm similarly unsure about the design. Perhaps we could parametrise by the type, for something like
My suspicion is that it might possibly be nice to construct such a list eventually, since we can store the structure of multiplicative groups as a product of cyclic groups. I'll submit a PR for Dirichlet characters soon, where I think similar ideas can be used. |
I've been exploring the idea of singletons in 8ecb8e9. They fit nicely for |
Since
PrimitiveRoot a
is an abstract data type with a hidden constructor (#130), functionisPrimitiveRoot' :: CyclicGroup a -> a -> Bool
is pretty much useless: even if it returnsTrue
, there are no means to use this boolean as an evidence to construct aPrimitiveRoot
value. And the only way to getPrimitiveRoot
is usingisPrimitiveRoot :: Mod n -> Maybe (PrimitiveRoot n)
, which runs (possibly expensive)cyclicGroupFromModulo
for each candidate.I do not have any good ideas at the moment, how to fix this.
The text was updated successfully, but these errors were encountered: