Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
Yeah guys. I confused myself. I forgot why I had to implement several + operators (^+^, ^+, ^+. etc.) for Vector class. Now I've got an idea again. Different names make a perfect sense. Thanks a lot. On Sat, Jan 24, 2009 at 6:34 AM, Luke Palmer lrpal...@gmail.com wrote: 2009/1/23 Brandon S. Allbery KF8NH allb...@ece.cmu.edu On 2009 Jan 23, at 17:58, Olex P wrote: class Vector v where (^+^) :: v - v - v class Matrix m where (^+^) :: m - m - m You can't reuse the same operator in different classes. Vector owns (^+^), so Matrix can't use it itself. You could say instance Matrix m = Vector m where (^+^) = ... No you can't! Stop thinking you can do that! It would be sane to do: class Vector m = Matrix m where -- matrix ops that don't make sense on vector Thus anything that implements Matrix must first implement Vector. Which is sane because matrices are square vectors with some additional structure, in some sense. Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
But you know it doesn't make too much sense because I also have to define addition Scalar + Vector (that means construct vector from scalar and add a vector), Vector + Scalar and so on. And as we are not able to overload operations in C++ like way we have to create several different operations even if their meaning is pretty close. Probably it's possible with ad hoc overloading but I don't know is it good idea. On Sat, Jan 24, 2009 at 1:56 PM, Alberto G. Corona agocor...@gmail.comwrote: What about making your Vector a instance of Num? you have + and * well defined , although * is not commutative in this case 2009/1/24 Olex P hoknam...@gmail.com Yeah guys. I confused myself. I forgot why I had to implement several + operators (^+^, ^+, ^+. etc.) for Vector class. Now I've got an idea again. Different names make a perfect sense. Thanks a lot. On Sat, Jan 24, 2009 at 6:34 AM, Luke Palmer lrpal...@gmail.com wrote: 2009/1/23 Brandon S. Allbery KF8NH allb...@ece.cmu.edu On 2009 Jan 23, at 17:58, Olex P wrote: class Vector v where (^+^) :: v - v - v class Matrix m where (^+^) :: m - m - m You can't reuse the same operator in different classes. Vector owns (^+^), so Matrix can't use it itself. You could say instance Matrix m = Vector m where (^+^) = ... No you can't! Stop thinking you can do that! It would be sane to do: class Vector m = Matrix m where -- matrix ops that don't make sense on vector Thus anything that implements Matrix must first implement Vector. Which is sane because matrices are square vectors with some additional structure, in some sense. Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
* Olex P hoknam...@gmail.com [2009-01-24 15:35:22+] But you know it doesn't make too much sense because I also have to define addition Scalar + Vector (that means construct vector from scalar and add a vector), Vector + Scalar and so on. And as we are not able to overload operations in C++ like way we have to create several different operations even if their meaning is pretty close. Probably it's possible with ad hoc overloading but I don't know is it good idea. Consider defining functions with meaningful names (like scalarPlusVector), you then can use them as infix operators: 5 `scalarPlusVector` Vector 1 2 3 -- Roman I. Cheplyaka :: http://ro-che.info/ Don't let school get in the way of your education. - Mark Twain ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
2009/1/24 Olex P hoknam...@gmail.com But you know it doesn't make too much sense because I also have to define addition Scalar + Vector (that means construct vector from scalar and add a vector), Vector + Scalar and so on. And as we are not able to overload operations in C++ like way we have to create several different operations even if their meaning is pretty close. Well, yeah, but their meaning isn't *the same*, so we don't give them the same name. For vectors, putting a carat (or other signifier like a dot) on the side of the operation which has the vector is relatively common practice. Scalar +^ Vector Vector ^+^ Vector And so on. And also, I wonder, what are you going and adding scalars to vectors for!? (I've heard of multiplying scalars by vectors -- that's in the definition of a vector space, but adding...?) Oh, instead of overloading a million operations that just work component-wise on vectors the way C++ guys do it, you can just define a higher-order function: vmap :: (Vector v) = (Double - Double) - v - v Or however it works out in your situation. Then you can reserve those precious symbols for things that are actually vectory, like inner products. Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
Concerning Scalar + Vector i.e. +^ it's just a shortcut. Very useful even if it's not good (?) from the design point of view. Also one could find useful shortcut like ., .=, ., .= which mean compare length of vector. It's not usual for vector algebra but probably still make sense. What I want to ask you guys can we define a function with arbitrary number of parameters? Actually not really arbitrary but just several possibilities (as we have with value constructors). For instance cross product can have 1, 2 or 3 vectors as inputs depends on the dimension. Is it 2d, 3d or 4d case. On Sat, Jan 24, 2009 at 3:59 PM, Luke Palmer lrpal...@gmail.com wrote: 2009/1/24 Olex P hoknam...@gmail.com But you know it doesn't make too much sense because I also have to define addition Scalar + Vector (that means construct vector from scalar and add a vector), Vector + Scalar and so on. And as we are not able to overload operations in C++ like way we have to create several different operations even if their meaning is pretty close. Well, yeah, but their meaning isn't *the same*, so we don't give them the same name. For vectors, putting a carat (or other signifier like a dot) on the side of the operation which has the vector is relatively common practice. Scalar +^ Vector Vector ^+^ Vector And so on. And also, I wonder, what are you going and adding scalars to vectors for!? (I've heard of multiplying scalars by vectors -- that's in the definition of a vector space, but adding...?) Oh, instead of overloading a million operations that just work component-wise on vectors the way C++ guys do it, you can just define a higher-order function: vmap :: (Vector v) = (Double - Double) - v - v Or however it works out in your situation. Then you can reserve those precious symbols for things that are actually vectory, like inner products. Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
2009/1/24 Luke Palmer lrpal...@gmail.com: And also, I wonder, what are you going and adding scalars to vectors for!? (I've heard of multiplying scalars by vectors -- that's in the definition of a vector space, but adding...?) You can do that in geometric algebra. The result is a multivector. But in that case, you'd probably be using a single multivector type. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
2009/1/24 Olex P hoknam...@gmail.com: What I want to ask you guys can we define a function with arbitrary number of parameters? Actually not really arbitrary but just several possibilities (as we have with value constructors). For instance cross product can have 1, 2 or 3 vectors as inputs depends on the dimension. Is it 2d, 3d or 4d case. You need type classes plus some language extension to do this properly. Here's an example using type families: class Vector v = Cross v where type CrossResult v cross :: v - CrossResult v instance Cross Vector2 where type CrossResult v = Vector2 cross (Vector2 x y) = Vector2 (-y) x -- is this the right operation? instance Cross Vector3 where type CrossResult v = Vector3 - Vector3 cross (Vector3 x1 y1 z1) (Vector3 x2 y2 z2) = Vector3 (y1*z2 - z1*y2) (z1*x2 - x1*z2) (x1*y2 - y1*x2) etc. A difficult exercise is to define these operations in terms of each other inductively so that it works for arbitrary vector types; you need vectors indexed on some type-level natural, plus a bunch of hackery in the instances to make it work. -- ryan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
Cool! Thanks Ryan! On Sat, Jan 24, 2009 at 8:31 PM, Ryan Ingram ryani.s...@gmail.com wrote: 2009/1/24 Olex P hoknam...@gmail.com: What I want to ask you guys can we define a function with arbitrary number of parameters? Actually not really arbitrary but just several possibilities (as we have with value constructors). For instance cross product can have 1, 2 or 3 vectors as inputs depends on the dimension. Is it 2d, 3d or 4d case. You need type classes plus some language extension to do this properly. Here's an example using type families: class Vector v = Cross v where type CrossResult v cross :: v - CrossResult v instance Cross Vector2 where type CrossResult v = Vector2 cross (Vector2 x y) = Vector2 (-y) x -- is this the right operation? instance Cross Vector3 where type CrossResult v = Vector3 - Vector3 cross (Vector3 x1 y1 z1) (Vector3 x2 y2 z2) = Vector3 (y1*z2 - z1*y2) (z1*x2 - x1*z2) (x1*y2 - y1*x2) etc. A difficult exercise is to define these operations in terms of each other inductively so that it works for arbitrary vector types; you need vectors indexed on some type-level natural, plus a bunch of hackery in the instances to make it work. -- ryan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
Seems like all telepath are on vacation, so you would have to show the code. On 24 Jan 2009, at 01:15, Olex P wrote: Hello Haskellers! It's probably a simple question but I can't find a proper solution... Suppose we have a class Vector which overloads (+) operation. I'd like to represent a Matrix data type as a set of vectors: data Matrix3 = M3 !Vector3 !Vector3 !Vector3 In this case (+) for matrices could be implemented as: (M3 r11 r12 r13) + (M3 r21 r22 r23) = M3 (r11 + r21) (r12 + r22) (r13 + r23) But GHC says about ambiguous occurrence. I don't understand why because it's should be pretty clear that rows are vectors and (+) has to be vector type as well. I could use Vector.+ instead but it doesn't look good. Probably I'm missing something. Any ideas? Cheers, Oleksandr. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
On Sat, 2009-01-24 at 01:30 +0300, Miguel Mitrofanov wrote: Seems like all telepath are on vacation, Now, now, you didn't let enough time elapse to know that for sure. jcc ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
On 24 Jan 2009, at 01:35, Jonathan Cast wrote: On Sat, 2009-01-24 at 01:30 +0300, Miguel Mitrofanov wrote: Seems like all telepath are on vacation, Now, now, you didn't let enough time elapse to know that for sure. They're always on vacation when you need one. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
2009/1/23 Olex P hoknam...@gmail.com Hello Haskellers! It's probably a simple question but I can't find a proper solution... Suppose we have a class Vector which overloads (+) operation. I'd like to represent a Matrix data type as a set of vectors: data Matrix3 = M3 !Vector3 !Vector3 !Vector3 In this case (+) for matrices could be implemented as: (M3 r11 r12 r13) + (M3 r21 r22 r23) = M3 (r11 + r21) (r12 + r22) (r13 + r23) But GHC says about ambiguous occurrence. I don't understand why because it's should be pretty clear that rows are vectors and (+) has to be vector type as well. I could use Vector.+ instead but it doesn't look good. Probably I'm missing something. Any ideas? I'm am seeing an image. It's a... a Vector class, with an operation (+). Oh, he's with another one though. It's the Num class. Oh they're fighting over the (+). Vector is trying to take it from Num, but Num isn't letting go. Why doesn't Vector see that there is a whole pile of operations neglected in the corner, like (^+^), (.+.). He just really wants that (+), huh... Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
Well if telepaths on vacation... class Vector v where (^+^) :: v - v - v data Vector3 = V3 !Double !Double !Double instance Vector Vector3 where (V3 x1 y1 z1) ^+^ (V3 x2 y2 z2) = V3 (x1 + x2) (y1 + y2) (z1 + z2) class Matrix m where (^+^) :: m - m - m data Matrix3 = M3 !Vector3 !Vector3 !Vector3 instance Matrix Matrix3 where (M3 r11 r12 r13) ^+^ (M3 r21 r22 r23) = M3 (r11 ^+^ r21) (r12 ^+^ r22) (r13 ^+^ r23) Hope this is better :) So yeah... r11 ^+^ r21 just doesn't work. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
2009/1/23 Olex P hoknam...@gmail.com: Well if telepaths on vacation... class Vector v where (^+^) :: v - v - v data Vector3 = V3 !Double !Double !Double instance Vector Vector3 where (V3 x1 y1 z1) ^+^ (V3 x2 y2 z2) = V3 (x1 + x2) (y1 + y2) (z1 + z2) class Matrix m where (^+^) :: m - m - m data Matrix3 = M3 !Vector3 !Vector3 !Vector3 instance Matrix Matrix3 where (M3 r11 r12 r13) ^+^ (M3 r21 r22 r23) = M3 (r11 ^+^ r21) (r12 ^+^ r22) (r13 ^+^ r23) Hope this is better :) So yeah... r11 ^+^ r21 just doesn't work. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe Luke's story about Num and a supposed Vector class is repeated here between Vector and Matrix classes. Either you make a class Add instanciated by both Vector and Matrix, or you use different name for each of them. Cheers, Thu ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
2009/1/23 Olex P hoknam...@gmail.com: class Vector v where (^+^) :: v - v - v data Vector3 = V3 !Double !Double !Double instance Vector Vector3 where (V3 x1 y1 z1) ^+^ (V3 x2 y2 z2) = V3 (x1 + x2) (y1 + y2) (z1 + z2) class Matrix m where (^+^) :: m - m - m data Matrix3 = M3 !Vector3 !Vector3 !Vector3 instance Matrix Matrix3 where (M3 r11 r12 r13) ^+^ (M3 r21 r22 r23) = M3 (r11 ^+^ r21) (r12 ^+^ r22) (r13 ^+^ r23) Hope this is better :) So yeah... r11 ^+^ r21 just doesn't work. It works fine if you make Matrix3 an instance of Vector. -- Dan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
2009/1/24 Dan Piponi dpip...@gmail.com: 2009/1/23 Olex P hoknam...@gmail.com: class Vector v where (^+^) :: v - v - v data Vector3 = V3 !Double !Double !Double instance Vector Vector3 where (V3 x1 y1 z1) ^+^ (V3 x2 y2 z2) = V3 (x1 + x2) (y1 + y2) (z1 + z2) class Matrix m where (^+^) :: m - m - m data Matrix3 = M3 !Vector3 !Vector3 !Vector3 instance Matrix Matrix3 where (M3 r11 r12 r13) ^+^ (M3 r21 r22 r23) = M3 (r11 ^+^ r21) (r12 ^+^ r22) (r13 ^+^ r23) Hope this is better :) So yeah... r11 ^+^ r21 just doesn't work. It works fine if you make Matrix3 an instance of Vector. -- Dan To paraphrase a bit, your Vector class simply means : a type is a Vector if it provides an operation having a - a - a has its type (and called ^+^). The Matrix class says exactly the same thing, so don't bother repeat that... and simply make Vector3 and Matrix3 instances of Vector (which could then be renamed in Add or Plus or something). Thu ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
On Fri, 2009-01-23 at 22:58 +, Olex P wrote: Well if telepaths on vacation... class Vector v where (^+^) :: v - v - v data Vector3 = V3 !Double !Double !Double instance Vector Vector3 where (V3 x1 y1 z1) ^+^ (V3 x2 y2 z2) = V3 (x1 + x2) (y1 + y2) (z1 + z2) class Matrix m where (^+^) :: m - m - m data Matrix3 = M3 !Vector3 !Vector3 !Vector3 instance Matrix Matrix3 where (M3 r11 r12 r13) ^+^ (M3 r21 r22 r23) = M3 (r11 ^+^ r21) (r12 ^+^ r22) (r13 ^+^ r23) Hope this is better :) So yeah... r11 ^+^ r21 just doesn't work. I think you mis-understand how classes work in Haskell. They aren't like classes in OO languages. They're a little bit like interfaces in OO languages, but here we see another difference: in OO, you know an object has a certain class, so you use that to find out what a method name means. In Haskell, it's the other way around: you know a method belongs to a certain class, so you know its argument (or result) must come from an instance of that class. You can't re-use method names for multiple classes, though - you have to either use different names (e.g., div vs. (/) in Prelude) or use a common base class. jcc ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
On 2009 Jan 23, at 17:58, Olex P wrote: class Vector v where (^+^) :: v - v - v class Matrix m where (^+^) :: m - m - m You can't reuse the same operator in different classes. Vector owns (^+^), so Matrix can't use it itself. You could say instance Matrix m = Vector m where (^+^) = ... allowing Matrix to inherit Vector's operator (or turn it around the other way, make it Matrix then make Vector a Matrix), but that's only linguistically possible, not necessarily mathematically sane. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to define an operation in terms of itself (but of different type)?
2009/1/23 Brandon S. Allbery KF8NH allb...@ece.cmu.edu On 2009 Jan 23, at 17:58, Olex P wrote: class Vector v where (^+^) :: v - v - v class Matrix m where (^+^) :: m - m - m You can't reuse the same operator in different classes. Vector owns (^+^), so Matrix can't use it itself. You could say instance Matrix m = Vector m where (^+^) = ... No you can't! Stop thinking you can do that! It would be sane to do: class Vector m = Matrix m where -- matrix ops that don't make sense on vector Thus anything that implements Matrix must first implement Vector. Which is sane because matrices are square vectors with some additional structure, in some sense. Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe