jcpetruzza / barbies

BSD 3-Clause "New" or "Revised" License
92 stars 15 forks source link

Lifting Semigroup and Monoid instance #25

Closed gergoerdi closed 4 years ago

gergoerdi commented 4 years ago

My main use case for Barbies is collecting partial output in a WriterT (out Covered Last) (State s), to be assembled to a full out Bare Identity by filling the missing fields from s. However, this requires out Covered Last to be a monoid.

Would it make sense to include the following generic lifting instance in Barbies itself, to avoid orphan instance problems? Note that Higgledy already includes the equivalent instances for HKD b f, but I'd like to move from Higgledy to Barbies + Barbies-TH (to have proper named fields).

instance (ApplicativeB (a Covered), forall b. Semigroup (f b)) => Semigroup (a Covered f) where
    (<>) = bzipWith (<>)

instance (ApplicativeB (a Covered), forall b. Monoid (f b)) => Monoid (a Covered f) where
    mempty = bpure mempty
gergoerdi commented 4 years ago

Actually, I have now found the Barbie newtype wrapper in the documentation, which says:

This can be use with deriving via to automate derivation of instances for Barbie-types.

so maybe this issue should be renamed to "document how to actually do that"...

I've tried in the following setting:

declareBareB [d|
  data CPUOut = CPUOut
      { _progAddr :: PC
      , _memAddr :: Ptr
      , _memWrite :: Maybe Cell
      , _output :: Maybe Cell
      , _inputNeeded :: Bool
      } |]

Some combinations I've tried:

deriving instance Semigroup CPUOut via Barbie
deriving instance Semigroup (CPUOut Covered f) via Barbie (CPUOut Covered) f
deriving instance Semigroup (CPUOut Covered Last) via Barbie (CPUOut Covered) Last
deriving instance Semigroup (CPUOut Covered) via Barbie (CPUOut Covered)
deriving instance Semigroup (CPUOut Covered) via Barbie

but they all give (quite unkind) kind errors.

gergoerdi commented 4 years ago

Ah, so turns out it should be

deriving via Barbie (CPUOut Covered) f instance (forall a. Semigroup (f a)) => Semigroup (CPUOut Covered f)
jcpetruzza commented 4 years ago

Have you tried using the Barbies.Barbie newtype-wrapper for this? It gives you the generic instances for Semigroup and Monoid and you should be able to use it with deriving via.

I’m curious if this works well enough for you?

jcpetruzza commented 4 years ago

sorry, saw your other messages too late! :smile: