msakai / data-interval

Interval datatype, interval arithmetic, and interval-based containers for Haskell
Other
21 stars 9 forks source link

width of open integer intervals is not right #39

Closed ulysses4ever closed 10 months ago

ulysses4ever commented 1 year ago

I checked out the master branch today to make sure that #38 is in, but I still get something wrong. Maybe I'm not getting something?

λ> import qualified Data.IntegerInterval as II
λ> II.width $ Finite 3 II.<..< Finite (5::Integer)
0

I think the width of this interval should be 1. Is that not right?

Even more surprising is the result for regular intervals:

λ> import Data.Interval
λ> width $ Finite 3 <..< Finite (5::Int)
2

How?…

Bodigrim commented 1 year ago

The first example is correct, I think: for Data.IntegerInterval an interval 3 <..< 5 gets normalized to 4 <=..<= 4, which is just a point, so width is zero.

The second case is surprising, but the thing is that Data.Interval has no means to distinguish between, say, Int and Double. I'd expect width $ Finite 3 <..< Finite (5 :: Double) to be 2, and so the same result is returned for Int. This intricacy could have been spelled out better.

A documentation improvement would be very welcome.

ulysses4ever commented 1 year ago

@Bodigrim this makes sense, thank you.

For the first case, let me ask a "user question" then: is there a way to count the number of integers residing in the given interval? That would be 1 for 4 <=..<= 4. I expected width to do that but your reply implies this is not the case. I'm still unsure why this is not the case. For the integer lattice, i think, the reasonable expectation for a function named width to return 1 in this case. But I'm happy to take anything that'd do the job.

I support improving docs for width to reflect what happens in the second case and in the light of the reasoning in the previous paragraph, but I don't feel like I understand the situation deeply enough to do that improvement, sorry.

By the way, I am actually forced to use Interval Int as opposed to IntegerInterval (I'd prefer IntInterval but that's fine) because I need IntervalSet. Is there a feeling that there could be a generic typeclass-based module for intervals, and a set module that would work against the type class rather than one particular instance of it (the Interval type)?

Bodigrim commented 1 year ago

For the first case, let me ask a "user question" then: is there a way to count the number of integers residing in the given interval?

For IntegerInterval this would be precisely (+1) . width.

For Interval Int one can implement it manually, using lowerBound' / upperBound'.

width does not really have any meaningful semantics for anything other than Interval Double, unfortunately.

Is there a feeling that there could be a generic typeclass-based module for intervals, and a set module that would work against the type class rather than one particular instance of it (the Interval type).

Probably yes, but I don't see it happening any time soon in this package.

ulysses4ever commented 1 year ago

Wonderful, thank you again for very helpful answers!