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

Reply via email to