Closed sheaf closed 4 years ago
Oops, I didn't think about that use case. It doesn't seem possible to get the old behavior, so instead we have to write the Monoid
instance by hand, and we even have to coerce it manually :(
instance Monoid a => Monoid (Vector2D a) where
mempty = Vector2D gmempty
-- also, on base < 4.11:
-- mappend = (<>)
I could add another newtype that does this, so we could write via SemigroupGenerically (Point2D (Sum a))
(modulo choosing a better name). (In hindsight, #18 should have been another newtype if I had anticipated this.)
One technicality is whether to define mappend
for that newtype as gmappend'
or (<>)
. It doesn't matter if all fields ensure that mappend = (<>)
syntactically; not even performance should be affected.
See also the readme for my acts library where I have
data Point2D a = Point2D !a !a
deriving stock ( Show, Generic )
deriving ( Act ( Vector2D a ), Torsor ( Vector2D a ) )
via Vector2D a
newtype Vector2D a = Vector2D { tip :: Point2D a }
deriving stock Show
deriving ( Semigroup, Monoid, Group )
via Generically ( Point2D ( Sum a ) )
I find it quite convenient to use a single newtype to derive the three different stuctures, and in my opinion it's a nice usability upside that this library has over generic-monoid.
Anyway it shouldn't matter too much, as even if Generically
keeps the current behaviour we can also provide a newtype which provides the old behaviour. Although I would prefer it to have a less specific name than SemigroupGenerically
, as I find deriving Monoid via SemigroupGenerically a
to be a bit weird.
So it looks like we will have to have two versions of Generically
, and backwards compatibility dictates that we don't touch the current Generically
(even though it is frustrating because the new behavior seems useful more often).
Arguably, a catch-all Generically
has limited applicability, because there is more than one implementation for most classes, such as Monoid
here (although the issue with this one really stems from a historical accident). So it is natural that we should be looking at different newtypes with more specialized meanings.
The main purpose here is to derive all three of Semigroup
, Monoid
and Group
from the same product structure, so I have the following name suggestions for the new newtype (in order of my preference):
GenericProduct
ProductType
AsProduct
The following code works with
generic-data-0.6.0.1
but notgeneric-data-0.7.0.0
due to #18:The changes in #18 mean that, when attempting to derive the
Monoid ( Vector2D a )
instance, GHC goes looking for aSemigroup ( Point2D ( Sum a ) )
instance as opposed to using theSemigroup ( Vector2D a )
instance that has just been generically derived.I understand that #18 enables generically deriving a
Monoid
instance while re-using the underlyingSemigroup
instance, but in my opinion it is more common to want to derive both instances at the same time.What's the equivalent way of writing the above example starting from version
0.7.0.0
of the library?