bodil / purescript-sized-vectors

Idris style sized vectors in PureScript
18 stars 12 forks source link

Add Semigroup and Monoid instances #20

Closed artemisSystem closed 4 years ago

artemisSystem commented 4 years ago

These work by individually appending the elements of the first vector to the corresponding element in the other vector, leaving the size the same. Example: vec3 "a" "b" "c" <> vec3 "d" "e" "f" is vec3 "ad" "be" "cf"

artemisSystem commented 4 years ago

There have been a lot of PRs, sorry if it's too much haha. I think if you merge the apply one, then the fix one, then the last ones in any order, things will work out fine. Otherwise i think some things might get weird, not sure.

athanclark commented 4 years ago

I'm not sure if this semigroup instance respects the "free monoid" idea behind haskell lists. In addition, this constrains the contained data to also have that instance, which isn't necessary imho. But, we can't really make a normal implementation due to the heterogeneous nature of (x :: Vec x a) <> (y :: Vec y a) = (z :: Vec (x + y) a). I'm not sure, I'd like some other comments on this idea.

artemisSystem commented 4 years ago

It's not going to be a monoid instance in any way like the list/array we know. But that doesn't really make sense for a fixed length list anyway. (Fixed length in the sense that any conventonal type class instances (Functor, Monad, Monoid) will have to retain the same array length throughout.) However, the type of instances that are useful (and IMO, perfect) for the Vec type are "zippy" ones, that is, instances which focus on "zipping" Vecs together. This is how the recently fixed Apply instance works. If we are to have a Semigroup/Monoid instance at all, it will have to retain the size of the Vec, and i feel like the only sensible way to do that is to <> each of them individually. An example use case would be adding positions in 3D (though it could be any dimension, really). You could store your vectors in a Vec D3 (Additive Int), and to add two of them together you would do vec3 (Additive 2) (Additive 3) (Additive 4) <> vec3 (Additive 3) (Additive 4) (Additive 5)

athanclark commented 4 years ago

This makes sense to me, I'll buy it!