[Haskell-cafe] Re: Difference between div and /

Richard O'Keefe ok at cs.otago.ac.nz
Wed Jun 2 20:44:39 EDT 2010

On Jun 3, 2010, at 1:13 AM, Maciej Piechotka wrote:

> On Wed, 2010-06-02 at 14:01 +1200, Richard O'Keefe wrote:
>> For what applications is it "useful" to use the same symbol
>> for operations obeying (or in the case of floating point
>> operations, *approximating* operations obeying) distinct laws?
> If the given operations do share something in common. For example * is
> usually commutative. However you do use it with quaternions (Hamilton
> product). You even write ij = k despite the fact that ji = -k.

I think you just made my point:  Commutativity is NOT one of the  
properties that * is EXPECTED to possess.  However, it IS one of the
properties that + is expected to possess, which is why Java's abuse of
+ for string concatenation is so bad.

> I gave the code which might have work for both Integral and Fractional
> but it is not possible to type it in Haskell.

This is what you wrote:

   If you have something like that:

   instance ... => Distribution (Linear a) a where
      rand (Linear f s) g =
          let (gf, gt) = genRange g
              (v, g') = next g
          in (g', f + (fromIntegral v * s) / fromIntegral (gt - gf))

Since I don't know what Linear is or what Distribution is
it's hard for me to tell exactly what this is supposed to do,
but I'll take a stab at it.

(Linear f s) specifies an interval by giving a starting
point f and a width s; the interval specified is the
half-open interval [f,f+s).

genRange g returns (l,u) where l is the smallest Int that g
can return and u is the largest Int that g can return; these
are INCLUSIVE bounds so the number of values to consider is
u-l+1.  For StdGen the bounds are (0,2147483562)

Let's just see what would happen if
  - we used this code
  - g was an instance of StdGen
  - f was 0       :: Int
  - s was 1000000 :: Int
  next g --> (1079700,g')	-- actual run
  fromIntegral 1079700 * 1000000 = 1079700000000
                                 = 1663208704 :: Int
   1663208704 `div` fromIntegral (2147483562 - 0) :: Int
    == 0

In fact almost all the answers you get will be 0.

If f and s are of any bounded integral type, this is NOT
going to do anything useful.   And it's NOT because / is
not aliased to div.  It's because multiplication overflows.

If you look at the Int and Double instance of Random in
the Random.hs that comes with Hugs, you'll see they use
different code.  It's not because of any problem with /
per se but because they need genuinely different algorithms.

More information about the Haskell-Cafe mailing list