On 6/20/07, Henning Thielemann <lemming@henning-thielemann.de> wrote:
Do you have some examples, where such a data type is really superior to
strong typing? There are examples like computing the average, where a
natural number must be converted to a different type:
average xs = sum xs / fromIntegral (length xs)
but this one can easily replaced by
average xs = sum xs / genericLength xs
Thus, before you spend much time on making Haskell closer to Perl, how
about collecting such examples, work out ways how to solve them elegantly
in the presence of strong typing and set up a wiki page explaining how to
work with strongly typed numbers? I think, this topic really belongs to
http://www.haskell.org/haskellwiki/Category:FAQ
Strongly typed numbers are there for good reason: There is not one type
that can emulate the others. Floating point numbers are imprecise, a/b*b=a
does not hold in general. Rationals are precise but pi and sqrt 2 are not
rational. People have designed languages again and again which ignore
this, and they failed. See e.g. MatLab which emulates an integer (and even
a boolean value) by a complex valued 1x1 matrix.
That's a good idea too, perhaps I will do that. This would be a good thing to have on the wiki since it's clearly an issue that people learning Haskell struggle with (I certainly did). I also want to make clear, though, that I certainly appreciate the reasons for strongly typed numbers. I am not trying to make Haskell closer to Perl in general (God forbid!), or in any way advocate for doing away with strongly typed numbers, but only to create a library for working more conveniently with numeric types in small programs where the typing is not as important. To give a couple quick examples, based on what I have already implemented:
*EasyNum> 1 / 3
0.3333333333333333
*EasyNum> 1 / 3 :: EasyNum
1/3
*EasyNum> 1 / floor pi
<interactive>:1:4:
Ambiguous type variable `t' in the constraints:
`Integral t' arising from use of `floor' at <interactive>:1:4-11
`Fractional t' arising from use of `/' at <interactive>:1:0-11
Probable fix: add a type signature that fixes these type variable(s)
*EasyNum> 1 / floor pi :: EasyNum
1/3
I would have also put in the example of 1 / pi :: EasyNum and show it printing out a double value instead of the rational it prints with 1 / 3, except I haven't yet implemented the instance of Floating. =)
-Brent