On 03/08/10 05:32, Gregory Crosswhite wrote:
I am pleased to announce the release of the package "approximate-equality",
which provides newtype wrappers that allow one to effectively override the equality
operator of a value so that it is/approximate/ rather than/exact/. The wrappers use
type annotations to specify the tolerance; the 'Digits' type constructor has been
provided for specifying the tolerance using type-level natural numbers. Instances for
all of the classes in the numerical hierarchy have been provided for the wrappers, so the
wrapped values can mostly be used in the same way as the original values. (In fact, most
of the time one doesn't even have to wrap the starting values, since expressions such as
(1+sqrt 2/3) are automatically wrapped thanks to the 'fromIntegral' method of the 'Num'
typeclass.)
The motivation behind this package is that there are times when working with
floating point numbers that one would like the equality operator to check for
approximate equality rather than exact equality. For example, in one of my own
projects I have a walker that spits out a list of coordinate values that I
keep track of, and since floating point arithmetic is inexact it will often
arrive at the same point from two different paths and thus obtain slightly
different values for the coordinates of that point. I could have just written
a function to do approximate matching of the point and be done with it, but
then I can't leverage pre-built data structures such as Data.Set and Data.Map
which use (==) for determining whether a key is a member.
This package is compatible with Haskell 2010, as it only uses the
EmptyDataDecls extension, and the only package dependency is
type-level-natural-numbers which itself is Haskell 2010.
Any feedback from the community is, of course, very welcome.
I like the look of this. Eq and Ord instances that use epsilon values
look like they will be handy. I have a design question/suggestion. You
have:
class AbsoluteTolerance absolute_tolerance where
absoluteToleranceOf :: Fractional value =>
AbsolutelyApproximateValue absolute_tolerance value -> value
Why do you need this class (and the other two)? It looks like you can
just define:
absoluteToleranceOf :: (NaturalNumber n, Fractional value) =>
AbsolutelyApproximateValue (Digits n) value -> value
absoluteToleranceOf = toleranceFromDigits . getAbsoluteTolerance
So you can get the same function without needing to add a type-class.
Or is it that you envisage other tolerance specifications besides
Digit? If so, I wonder if this flexibility complicates your API
unnecessarily. If you removed those type-classes and just stuck with
Digits, the size of your API documentation would halve, and make the
docs a lot more readable.
Thanks,
Neil.
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe