
On 23 March 2014 11:58, Bart Massey
My complaint with numeric-prelude is that it doesn't (and arguably can't) fix the problems that for me make Haskell borderline usable for actual engineering work involving actual "normal" numbers, and genuinely somewhat unusable for teaching: Off the top of my head:
* The lack of implicit conversions (except for the weird defaulting of literals, which means that I am constantly writing `fromIntegral` and `toRealFrac` in places where there is only one reasonable choice of type conversion, and occasionally having things just malfunction because I didn't quite understand what these conversion functions would give me as a result.
Prelude> 3 + 3.5 6.5 Prelude> let x = 3 Prelude> x + 3.5
<interactive>:4:5: No instance for (Fractional Integer) arising from the literal `3.5' Possible fix: add an instance declaration for (Fractional Integer) In the second argument of `(+)', namely `3.5' In the expression: x + 3.5 In an equation for `it': it = x + 3.5 Prelude>
I mean, seriously? We expect newbies to just roll with this kind of thing?
Isn't this more of a ghci issue than a Haskell issue? I actually think it's good behaviour that - in actual code, not defaulted numerals in ghci - we need to explicitly convert between types rather than have a so-far-Integer-value automagically convert to Double.
Even worse, the same sort of thing happens when trying to add a `Data.Word.Word` to an `Integer`. This is a totally safe conversion if you just let the result be `Integer`.
What would be the type of such an operation be? I think we'd need some kind of new typeclass to denote the "base value", which would make the actual type signature be much more hairy.
* The inability of Haskell to handle unary negation sanely, which means that I and newbies alike are constantly having to figure things out and parenthesize. From my observations of students, this is a huge barrier to Haskell adoption: people who can't write 3 + -5 just give up on a language. (I love the current error message here, "cannot mix `+' [infixl 6] and prefix `-' [infixl 6] in the same infix expression", which is about as self-diagnosing of a language failing as any error message I've ever seen.)
This is arguably the fault of mathematics for overloading the - operator :p
* The multiplicity of exponentiation functions, one of which looks exactly like C's XOR operator, which I've watched trip up newbies a bunch of times. (Indeed, NumericPrelude seems to have added more of these, including the IMHO poorly-named (^-) which has nothing to do with numeric negation as far as I can tell. See "unary negation" above.)
* The incredible awkwardness of hex/octal/binary input handling, which requires digging a function with an odd and awkward return convention (`readHex`) out of an oddly-chosen module (or rolling my own) in order to read a hex value. (Output would be just as bad except for `Text.Printf` as a safety hatch.) Lord knows what you're supposed to do if your number might have a C-style base specifier on the front, other than the obvious ugly brute-force thing?
* Defaulting numeric types with "-Wall" on producing scary warnings.
Prelude> 3 + 3
<interactive>:2:3: Warning: Defaulting the following constraint(s) to type `Integer' (Num a0) arising from a use of `+' In the expression: 3 + 3 In an equation for `it': it = 3 + 3
<interactive>:2:3: Warning: Defaulting the following constraint(s) to type `Integer' (Num a0) arising from a use of `+' at <interactive>:2:3 (Show a0) arising from a use of `print' at <interactive>:2:1-5 In the expression: 3 + 3 In an equation for `it': it = 3 + 3 6
and similarly for 3.0 + 3.0. If you can't even write simple addition without turning off or ignoring warnings, well, I dunno. Something. Oh, and try to get rid of those warnings. The only ways I know are `3 + 3 :: Integer` or `(3 :: Integer) + 3`, both of which make code read like a bad joke.
So above you didn't like how ghci defaulted to types too early, now you're complaining that it's _not_ defaulting? Or just that it gives you a warning that it's doing the defaulting?
Of course, if you write everything to take specific integral or floating types rather than `Integral` or `RealFloat` or `Num` this problem mostly goes away. So everyone does, turning potentially general code into needlessly over-specific code.
Not sure I'm done, but running out of steam. But yeah, while I'm fine with fancy algebraic stuff getting fixed, I'd also like to see simple grade-school-style arithmetic work sanely. That would let me teach Haskell more easily as well as letting me write better, clearer, more correct Haskell for that majority of my real-world problems that involve grade-school numbers.
--Bart _______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
-- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com http://IvanMiljenovic.wordpress.com