Le 26/03/2012 01:51, Chris Smith a écrit :
> instance (Num a) => Num [a] where
> xs + ys = zipWith (+) xs ys
You can do this in the sense that it's legal Haskell... but it is a
bad idea to make lists an instance of Num, because there are
situations where the result doesn't act as you would like (if you've
had abstract algebra, the problem is that it isn't a ring).
More concretely, it's not hard to see that the additive identity is
[0,0,0...], the infinite list of zeros. But if you have a finite list
x, then x - x is NOT equal to that additive identity! Instead, you'd
only get a finite list of zeros, and if you try to do math with that
later, you're going to accidentally truncate some answers now and then
and wonder what went wrong.
In general, most type classes in Haskell are like this... the compiler
only cares that you provide operations with certain types, but the
type class also carries around additional "laws" that you should obey
when writing instances. Here there's no good way to write an instance
that obeys the laws, so it's better to write no instance at all.
Sorry, Chris, I disagree quite strongly.
You begin badly: "the problem is that it isn't a ring".
Who told you so?
It MIGHT be a ring or not. The "real problem" is that one should not
confuse structural and algebraic (in the "classical" sense) properties
of your objects.
1. You may consider your lists as representants of polonomials. A very
decent ring.
2. I used hundred times lists as representants of power series.
Infinite, potentially, but often having just finite number of non-zero
coefficients, and if those could be divided, the list was not only a
ring, but a field. (Doug McIlroy did that as well, and his papers on
power series are much better known than mine...) And NO, no truncation
"problems", if you know how to program correctly. The laziness helps.
3. A very similar stuff to series or polynomials is the usage of lists
as differential algebras (uni-variate). I needed not only the numerical
instances, but a derivation operator. A ring, a field, *different* from
the previous ones.
4. I wanted to have the "trajectories" - the numerical sequences which
were solutions of differential equations, to behave as mathematical
objects that could be added, scaled, etc. A vector space, and much more.
5. I used lists as signals which could be added (sound composition),
multiplied (modulation), etc. Good rings. Totally different from the
previous ones.
Whether it would be better to use some specific ADT rather than lists,
is a question of style. The fact that - as you say - "there's no good
way to write an instance that obeys the laws" won't disturb my sleep.
You know, there is no good way to organise a society where everybody
obeys the Law. This is no argument against the organisation of a Society...
Thank you.
Jerzy Karczmarczuk
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe