[To give people that use threaded e-mail readers a helping hand,
I'd like to encourage posters to use followup/reply when responding,
so that the desired headers are included. -moderator]
Discussing the Numbers in Haskell.
I wrote
Not only Complex but the Real numbers too are impossible to be
presented adequately algorithmically.
Hans Aberg <[EMAIL PROTECTED]> replies:
A> Strictly speaking, the "real numbers" should be called floating numbers,
A> which one usually does in computer contexts if being more accurate.
Yes. It is, probably, right to call them Float and ComplexFloat.
Hans also writes
A> In pure math, given a ring $R$, one speaks about its complexification
A> $R_\C = $R \tensor_\Z \Z[i]$ (using LaTeX commands and \tensor = \otimes,
A> \C = \mathbb{C}, \Z = \mathbb{Z}), where $\Z[i]$ are the integers extended
A> with a complex unit $i$. More explicitly, the complexification $R_\C$ will
A> consist of pairs $r + i s$, where $r, s \in R$, $i$ is a formal symbol, and
A> addition, multiplication and so on uses the rules for the usual complex
A> numbers.
A>
A> So, why not add a type "Complexify(R)" of a ring R to Haskell?
I agree.
Complexify(R) means to extend R algebraically with rootOf( x^2+1 ).
Similarly, we can extend R with rootOf( x^3-2 ) and obtain the
expressions with cubicRoot(2), and so on.
Where Haskell has to stop and leave the rest for the applied programs?
Probably, better to stop after Complexify(R). Because it does not
need the polynomial parameter in its data.
Felix Schroeter <[EMAIL PROTECTED]> writes on "Complexify(R)" :
> Note that you can't divide in a ring.
Some rings are *fields*. For example, R = Rational.
In such rings there exists a good division.
CR = Complexify(R) has to define the division for CR or not depending
on whether R is an instance of Field.
Generally, Cp(Q) = Complexify(Rational)
is more practicable than Cp(Z) = Complexify(Integer)
because Cp(Q) contains Cp(Z) inside it and possesses a good division.
It consists of the values like (2+3*i)/(1-5*i).
Jan Skibinski <[EMAIL PROTECTED]> writes
S> One of the benefits of having Complex closely coupled
S> with other numbers is its potential utilization
S> in error handling. So far, evaluation of sqrt (-1)
S> produces unrecoverable error. But the answer could
S> be the legal complex 0:+1 - providing that the instance
S> (-1) (currently Floating a) knows about Complex.
S> ...
Improving sqrt(-1) for ComplexFloat is a matter of casting the
argument (maybe, automatically) from Integer to ComplexFloat.
To my mind, this all has to work like this:
rootN 2 9 --> Just 3 :: Maybe Integer
rootN 2 8 --> Nothing :: Maybe Integer
rootN 2 ((-1) `cv` c) --> Just (Cp 0 1) :: Maybe CI -- 0 + i*1
rootN 2 ((-2) `cv` f) --> Just (Cp ...) :: Maybe CF --floating
type CI = Complexify Integer
type CF = Complexify Float
c = Cp 0 0 :: CI -- any CI element.
f = Cp 0 0 :: CF
Here cv converts (-1) to the types CI,CF.
And in all cases
rootN :: (CommutativeRing a...) => Integer -> a -> Maybe a
Of course, Integer,CI,CF have different definitions of the rootN
class operation.
The conversion cv *can often be performed implicitly* by the
complier. There exists a proposal of how to arrange this with the
particular means of Haskell instance mechanism:
ftp.botik.ru:/pub/local/Mechveliani/typeConvProposal.txt
fromInteger would not help in general. Because next time we will, for
example, have to convert from CI to CF.
S> Say you want to find roots of some polynomial.
S> You start with real coefficients, but in many cases
S> you end up with complex roots. Real roots are just
S> a special case.
The same is with the eigenvalues, polynomial roots, and so on: it
depends mostly on *were* (to which type) the initial argument is cast,
- explicitly or implicitly, - before really applying the operation.
S> For me Floating is just one possible approximation of Real.
S> ...
S> In contrary, sticking for a moment to a continued fraction, I can
S> think of any desired accuracy of a representation of an Irrational
S> number that can achieved this way.
S>...
S> specify the accuracy and the sqrt function would do all
S> what is needed to achieve it.
S>
S> Same way we could compute pi, e, sinh, etc. And as I
S> was saying in my original post - there are better ways
S> of doing this. And more efficient too! What I understand,
S> the efficient implementations of Irrationals are around
S> the corner.
This is all right. Personnaly, i would be glad to see
data IntLike a => ContinuedFraction a = CtF [a] (Integer->a) ...
supplied with many clever instances to emulate the Real numbers more
closely.
Only this is not for the Haskell standard library. It is too complex.
This is a business for the *applied programs*.
>> The main issue on Maple, Matlab, Mathematica ... is that they are the
>> computer algebra systems.
>> And Haskell is an universal programming language and tool.
So? Eiffel was also conceived as a general language,
until they realized the need for math library.
Same with C and other languages. And now you have
wavelets and The Best Fourier Transform On The West
(or whatewever they call it) implemented in C.
And better to leave this Fourier transform to applications.
Otherwise, what is the difference between Eiffel and the programs
written in Eiffel?
Why not put all the science inside the Eiffel or Haskell compiler?
A reasonable approach is to provide a small library and concentrate on
the compiler progress itself, program transformation, specialization
technique, and such things.
Simon P.Jones <[EMAIL PROTECTED]> writes now
> ... the existence of good libraries has a big effect on how much
> use a language gets.
Good library means, to my mind, small and efficiently implemented.
> Bottom line: Haskell 2 is pretty wide open. ...
> ...
> ... Sergey's work is moving in that direction, which is great.
OK.
I start now and shall try to put the algebraic hierarhy proposal
before September. Then we will see how the Haskell people would
accept it.
------------------
Sergey Mechveliani
[EMAIL PROTECTED]