Closed Bodigrim closed 6 years ago
I like this idea a lot, although it seems like the Prime constructor is being exported - unless I'm missing something. Is this a good idea?
It is exported from Math.NumberTheory.Primes.Types
, because we create primes in many different modules. But it is not accessible for end user, because Math.NumberTheory.Primes.Types
is not an exposed module.
I'll take a look at this next weekend.
@Bodigrim related to but not contained by this PR, there's another issue I wanted to fix as well which is user-facing modules. For example, all of these modules:
Math.NumberTheory.ArithmeticFunctions
Math.NumberTheory.ArithmeticFunctions.Class
Math.NumberTheory.ArithmeticFunctions.Mertens
Math.NumberTheory.ArithmeticFunctions.Moebius
Math.NumberTheory.ArithmeticFunctions.SieveBlock
Math.NumberTheory.ArithmeticFunctions.Standard
(seen from 0.7.0.0, the latest version)
are exported by the package, when either
Math.NumberTheory.ArithmeticFunctions
or
Math.NumberTheory.ArithmeticFunctions.Class
Math.NumberTheory.ArithmeticFunctions.Mertens
Math.NumberTheory.ArithmeticFunctions.Moebius
Math.NumberTheory.ArithmeticFunctions.SieveBlock
Math.NumberTheory.ArithmeticFunctions.Standard
should be exported. In my opinion, at least. There's no use in having a reexporting module if the reexported modules are exported by themselves too.
@Bodigrim, makes sense, thanks! I'll take a closer look before next week.
There's no use in having a reexporting module if the reexported modules are exported by themselves too.
I am not convinced that this is necessarily true in general. It may be convenient in some cases. But following your suggestion I've hidden Math.NumberTheory.ArithmeticFunctions.{Class,Standard}
(which are reexported in full from Math.NumberTheory.ArithmeticFunctions
) to other-modules
in https://github.com/cartazio/arithmoi/commit/08f3f1472e2430ef85e4e14b85b46d8371ce19ea.
I agree with the general idea of the PR, and I've taken a look at all the changes (not at once).
Have you run all benchmarks from before and after the modifications to see if there's any significant change?
I run benchmarks, they look good.
This is a big breaking change, introducing (after all this time) a newtype for primes.
Remove 'Prime' type family and introduce 'Prime' newtype
Two years ago I designed a 'Prime' type family:
The idea was that a type for primes should contain only such prime elements
p
for whichabs p == p
, and this invariant must be forced by construction. It appeared that this approach has serious drawbacks.It is difficult to design
Prime a
for other unique factorisation domains. For example, even if we definedata GaussianPrime = GaussianPrime Natural Natural
(which is not very convenient), it still contains both associated primesGaussianPrime 3 0
andGaussianPrimes 0 3
. And things become even worse forEisensteinInteger
.Conversion from
Prime Integer
toInteger
is not free. (Conversion fromPrime Int
toInt
is almost free.)Since the type family is not injective you need a type annotation each time you use
unPrime
. For instance, GHC cannot determine which is the type ofunPrime (Prime 1)
. Is itNatural
orInteger
?That said, I decided to switch from a type family to a newtype:
Since
Prime
is used inUniqueFactorisation
type class, it underwent breaking transformation as well.Use 'Prime' newtype in user-facing functions
I decided do not re-export
Math.NumberTheory.Primes.{Factorisation,Testing}
fromMath.NumberTheory.Primes
, but exposePrime
- andUniqueFactorisation
-based interface instead. My intention is to show best and up-to-date practices first and hide an outdated low-level interface, which often confuses users.Sieve functions changed they output from
a
toPrime a
:I expect this to be a major breakage, but I see no way to sweeten it.
Also
nthPrime
changed it return type and outputsPrime Integer
now.@b-mehta @rockbmb what is your opinion?