Burning more bridges (mostly numeric ones)

Casey McCann cam at uptoisomorphism.net
Wed Mar 26 15:10:19 UTC 2014


On Tue, Mar 25, 2014 at 6:54 PM, wren romano <winterkoninkje at gmail.com> wrote:
>>> * 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.)
>>
>> It is unfortunate, but there really is a distinction being made.
>
> I'd go even farther and say that this is another case where Haskell is
> doing the right thing. There's a fundamental distinction going on
> here. The only complaints I have here are:
>
> 1) Because the type of the second argument to (^) and (^^) is
> polymorphic, numeric literals introduce warnings about defaulting.
> This is the one place where needing to make coercions explicit really
> does get on my nerves.

This situation really should not be a warning. It's an Integral
constraint on a type in contravariant position, which by itself can
only be ambiguous if it's given something built from numeric literals
and basic arithmetic. Having an Integral instance means a type
supports conversions to and from Integer, and I would be very dubious
about a type where (fromInteger . toInteger) was not equivalent to id.
I really can't see how defaulting an Integral constraint alone to
Integer is anything other than safe and sensible.

Unfortunately the same type may have other class constraints for which
defaulting to Integer would be ridiculous, and if memory serves me the
way defaults work doesn't distinguish between the clearly
sensible-to-default "6 ^ 12" and the equally not sensible "3 ^ read
userInput". In fact, I'd prefer that any type with a Read constraint
not default at all, ever. That's just asking for trouble.

On the other hand, a warning probably makes sense when defaulting a
type with e.g. a Show constraint, or Num (without Integral as well).

I'm not sure what exact rules would make the most sense here, but I
don't think the current defaulting mechanism would support anything
more sophisticated anyhow, so it's not a library issue.

> 2) (^) does not restrict the second argument to non-negative values
> and thus can throw runtime errors, when it really should be a type
> error.

...which would require a Natural type similar to Integer, and probably
the corresponding type classes as well, which among other things
entails adding a superclass to Num containing fromNatural (and,
ideally, containing (+) and (*) as well).

That's a pretty big bridge to burn, albeit a very temptingly flammable one.

- C.


More information about the Libraries mailing list