int to float problem (resend with addendum)

Matthew Donadio m.p.donadio@ieee.org
Wed, 05 Mar 2003 22:54:22 -0500


b.i.mills@massey.ac.nz wrote:
> Basically, from the algebraic perspective, the float type is
> a messy fudge, and does not fit in nicely with any of the
> "pure" types. In general the containment

I agree with what you said, but I think you may have missed my point.

In numeric programming, at least what I am currently working on, numeric
types are very often mixed.  With all of the syntactic sugar that
Haskell has to make the progarmmer's life easier, and programs easier to
read, I find it odd that there is no mechanism to control implicit type
coersion.

The two biggest examples I can think of are Int to Float (or Double) and
Float to Complex Float.

Consinder a direct translation of a discrete Fourier transform

> dft :: Array Int (Complex Double) -> Array Int (Complex Double)
> dft a = dft' a w n
>     where w = listArray (0,n-1) [ cis (-2 * pi * fromIntegral i / fromIntegral n) | i <- [0..(n-0)] ]
>	    n = snd (bounds a) + 1

> dft' :: Array Int (Complex Double) -> Array Int (Complex Double) -> Int -> Array Int (Complex Double)
> dft' a w n = listArray (0,n-1) [ sum [ a!k * wik i k | k <- [0..(n-1)] ] | i <- [0..(n-1)] ])
>     where wik i k = w!(i*k `mod` n)

In the defintion of w, the fromIntegrals serve no purpose other than to
make everything type.  This seems to go against the merits of
declarative programming.

Also consider the multiplication of a Complex Double by a Double.  There
are two ways to do this.  One is to make the scalar a complex, but this
turns what should be two multiplications into four mults and two adds if
the zero valued imaginary term doesn't get optimized out.  

> scale1 :: Complex Double -> Double -> Complex Double
> scale1 z x = z * (x :+ 0)

The second way to handle this is to expand the complex term into real
and imaginary parts, and do the multiplication.

> scale2 :: Complex Double -> Double -> Complex Double
> scale2 (zr :+ zi) x = (zr * x) :+ (zi * x)

Again, these two methods are needed only to make the functions type.

I am not advocating C / FORTRAN style type coersion.  What I am wishing
for is a per module or per function mechanism for giving the programmer
a way to state how coersion should take place, with the default being
none.  A new language feature would be great, but I would settle for a
pragma.

-- 
Matthew Donadio (m.p.donadio@ieee.org)