On 10/31/10 6:36 PM, Alexey Khudyakov wrote:
On Wed, Oct 27, 2010 at 2:53 AM, wren ng thornton wrote:
Is there any good reason for forcing them together? Why not, use the
hierarchy I proposed earlier?
[...]

Main reason is that it complicate creation of instances for types for which
multiplication is associative and commutative more complicated.
Programmer must write three instances instead of one and they must
satisfy some law. It leads to code which more difficult to understand and
contain more bug (mostly dumb).

Regardless of the class API instances must obey the law (or else have buggy results), so the law is uninteresting. We implicitly use such laws all the time, but usually we do so without having a class constraint to make our assumptions explicit. Isn't making assumptions explicit part of the reason for using a strongly typed language?

And as I mentioned previously, the burden of implementation is 2 or 3 *lines* of code. Talking about the number of class instances people must write is obfuscating the fact that it's trivial to add two lines of code. And this is code that gets written once, in a library.

This is tradeoff between usability and generality.

Your proposal, like so many I've seen before, is unusable because it lacks the necessary generality. The complexity of my proposal is insignificant: it requires only 2~3 lines of code, and an acknowledgment that there are structures other than vectorspaces.

Modules are much less
frequent and much less known than vector space.

Modules are more frequent than vector spaces, by definition, because every vector space is a module. Since you're not requiring Fractional(Scalar v), there isn't even any difference between them in the class API.

Your claim is like saying that we shouldn't have support for Applicative because Monads are more common. Again, there are more applicative functors than monads, the only cognitive overhead of having the Applicative class is acknowledging that there are structures other than monads, and adding Applicative enables a helpful style of programming which there is no reason to exclude.


One possibility is to add separate type classes for left and right modules
and require that is type is has both Module and LeftModule instances
(*^^) == (*^)

   class Module v where
     (^*) :: v ->  Scalar v ->  v
     (*^) :: Scalar v ->  v ->  v

Of course code that is written to work with left/right modules wont work with
associative modules.

Which my proposal fixes by making associative modules a subclass of both left- and right-modules.

--
Live well,
~wren
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to