
On Mon, 10 Apr 2006, Andrew U. Frank wrote:
there has been discussions on and off indicating problems with the structure of the number classes in the prelude. i have found a discussion paper by mechveliani but i have not found a concrete proposal on the haskell' list of tickets. i hope i can advance the process by making a concrete proposal for which i attach Haskell code and a pdf giving the rational can be found at ftp://ftp.geoinfo.tuwien.ac.at/frank/numbersPrelude_v1.pdf
Why are Zeros and Ones separated from the classes providing the operations? Since groups are required to have a neutral element and rings must have both a neutral additive element and a neutral multiplicative element, it makes sense to me, to couple Additive group with a zero and a Ring structure with a one. I guess you want to separate them because there are vectors and matrices of different sizes which we subsume under the same Haskell type. I have not seen a convincing solution for this problem so far. Indeed there are proposals implicit parameters, local type class instances and so on. The problem arises also for residue classes. I have worked around that problem by not comparing with a generated zero, but use a special isZero method. If I need a zero or a one in an algorithm I make it a parameter of the algorithm. Sometimes this leads to a nice generalization of an algorithm, if callers provide values different from zero. gcd+lcm, quot+rem, div+mod: In NumericPrelude quot+rem and div+mod are in separate classes. 'quot' and 'rem' need a notion of rounding towards zero. They are less general than 'div' and 'mod'. Actually I have never found an appriopriate application of 'quot' and 'rem'. When I saw them in other programs, 'div' or 'mod' were always the better choice. Also in NP 'gcd' and 'lcm' are separated from 'div' and 'mod', because the greatest common divisor cannot be always computed by the Euclidean algorithm. (^), (^^), (**): I found the distinctions of powers very useful and I would even refine them. In mathematical notation we don't respect types and we do not distinguish between powers of different types. However if we assume the most general types for both basis and exponent, the result of the power is no longer unique. Actually all possible solutions of say 1^x, where x is irrational is dense in the complex unit circle. In the past I needed the power of two complex numbers only once, namely for the Cauchy wavelet: f(t) = (1- i*k*t) ^ (-1/2 + mu2/k + i*mu1) http://www.math.uni-bremen.de/~thielema/Research/cwt.pdf http://ieeexplore.ieee.org/iel5/78/18506/00852022.pdf?arnumber=852022 However, I could not use the built-in complex power function because the resulting function became discontinuous. Of course, powers of complex numbers have the problem of branch cuts and the choice of the branch built into the implementation of the complex power is quite arbitrary and might be inappropriate. But also for real numbers there are problems: For computing (-1)**(1/3::Double) the power implementation has to decide whether (1/3::Double) is close enough to a third. If it does so it returns (-1) otherwise it fails. However, why shall 0.333333333333333 represent 1/3? It may be really meant as 333333333333333/10^15, and a real 10^15th root of (-1) does not exist. So I propose some balancing: The more general the basis the less general the exponent and vice versa. I also think the following symbols are more systematic and intuitive: any ring (provides *) ^ cardinal any field (provides /) ^- integer an algebraic field ^/ rational (computing a list of powers depending on the denominator of the rational) positive real (including transcendent) ^? anything (unqiue via exponential series) That is (^-) would replace (^^), (^?) would replace (**), (^) remains and (^/) is new. Branch cuts are a problem for all functions based on logarithms, apart from log and (**) these are: asin, acos, atan, asinh, acosh, atanh. I wonder how to treat them. I thought whether a residue class type would help. However a residue class with respect to the transcendent number pi would lead to a lot of rounding problems and the residue classes could be hardly processed further. So I'm thinking about a logarithm which returns a list of possible solutions. However for real numbers the logarithm is unique. I come to the conclusion that real logarithms and associated functions are considerably different from there generalizations to complex numbers. How to resolve that in type classes?