[Haskell-cafe] Why does the class called "Real" support only
rationals, and not all reals?
Henning Thielemann
lemming at henning-thielemann.de
Mon Jun 4 09:47:14 EDT 2007
On Sun, 3 Jun 2007, bretm wrote:
> I just got started learning Haskell a few days ago. I've implemented a
> numeric data type that can represent some irrational numbers exactly, and
> I'd like to instantiate the RealFrac class so I can do truncate, round,
> etc., in the most natural way in the language.
There are several things that are inconvenient in the numeric part of
Haskell 98 Prelude. As always I suggest a look at alternative numeric
class hierarchies, like NumericPrelude:
http://www.haskell.org/haskellwiki/Applications_and_libraries/Mathematics#Type_class_hierarchies
Is your approach more like symbolic calculation or more like a
representation for computable reals?
http://www.haskell.org/haskellwiki/Applications_and_libraries/Mathematics#Number_representations
> Implementing properFraction (which is in RealFrac) would not a problem at
> all, but implementing RealFrac requires implementing Real, which has the
> function toRational, which Haskell 98 says "returns the rational equivalent
> of its real argument with full precision" which isn't possible for this
> number type (which includes irrationals).
This obviously assumes, that all representations of reals in a computer
must be actually rationals. But in Haskell with lazy evaluation this is
not true:
http://darcs.haskell.org/numericprelude/src/Number/Positional.hs
> So my questions are: 1) Am I understanding the Haskell numeric classes
> correctly by thinking that to define properFraction I also have to define
> (incorrectly in this case) the toRational function? 2) Is a literal reading
> of Haskell 98 necessary for toRational or can it just be approximate? (Seems
> like not, since there's approxRational, and no other way to indicate the
> desired accuracy for toRational.)
In your case approximate would be the only possibility, I guess. Like
computations with Float and Double are approximate.
> As an example, consider a data type that can represent a quadratic surd,
> e.g. (1, 5, 2) might mean (1 + (sqrt 5)) / 2.
With NumericPrelude you can work with such numbers using polynomials
modulo the "polynomial" (x^2-5).
$ make ghci
*Main> ResidueClass.concrete (polynomial [-5,0,1::Rational]) (polyResidueClass [1,1] / 2 * polyResidueClass[1,1] / 2)
Polynomial.fromCoeffs [3 % 2,1 % 2]
meaning
(1 + sqrt 5) / 2 * (1 + sqrt 5) / 2 = (3 + sqrt 5) / 2
More information about the Haskell-Cafe
mailing list