Skip to content

Question: Combining bi-functors/nesting and with covering/stripping #55

@alaendle

Description

@alaendle

Hi, first thank you for this library - I really love the approach ❤️.
While I am playing around with modelling a data type that I can view both as a "whole" (Identity) and as "patch" (Maybe) - so that the can add patches (Semigroup) and apply them also to the whole object I stumbled around the following problem/question (but I'm pretty sure this is due to some misconception or limited knowledge on my side - but maybe you can point me to the right direction):

How can I combine bi-functors/nesting with covering/stripping?

To illustrate my problem:

data Foo f f' = Foo { foo :: f Int, fooBar :: f (Bar f') } deriving (Generic, FunctorB)

deriving instance FunctorT Foo
deriving instance ApplicativeT Foo

deriving instance (Show (f Int), Show (f (Bar f'))) => Show (Foo f f')
instance Alternative f => Semigroup (Foo f f') where
  (<>) = tzipWith (<|>)

instance Alternative f => Monoid (Foo f f') where
  mempty = tpure empty

data Bar f = Bar { bar :: f Int } deriving (Generic, FunctorB, ApplicativeB)

deriving instance Show (f Int) => Show (Bar f)

instance Alternative f => Semigroup (Bar f) where
  (<>) = bzipWith (<|>)

instance Alternative f => Monoid (Bar f) where
  mempty = bpure empty

This code works fine, but my problems begin to arise if I try to model using Wear to get rid of Identity for the "whole".

data Foo t f f' = Foo { foo :: Wear t f Int, fooBar :: Wear t f (Bar t f') } deriving (Generic)

deriving instance FunctorB (Foo Bare f)
deriving instance Functor f => FunctorB (Foo Covered f)
deriving instance FunctorT (Foo Covered)
deriving instance ApplicativeT (Foo Covered)

deriving instance (Show (Wear t f (Bar t f')), Show (Wear t f Int)) => Show (Foo t f f')
instance Alternative f => Semigroup (Foo Covered f f') where
  (<>) = tzipWith (<|>)

instance Alternative f => Monoid (Foo Covered f f') where
  mempty = tpure empty

data Bar t f = Bar { bar :: Wear t f Int } deriving (Generic)

deriving instance FunctorB (Bar Bare)
deriving instance FunctorB (Bar Covered)
deriving instance ApplicativeB (Bar Covered)
deriving instance Show (Wear t f Int) => Show (Bar t f)
instance BareB Bar
instance Alternative f => Semigroup (Bar Covered f) where
  (<>) = bzipWith (<|>)

instance Alternative f => Monoid (Bar Covered f) where
  mempty = bpure empty

And now to my problem - how to cover Foo?

works :: Bar Bare Identity -> Bar Covered Identity
works = bcover

how :: Foo Bare Identity Identity -> Foo Covered Identity Identity
how =bcover -- Couldn't match kind ‘* -> *’ with ‘*’ ...

For sure, by looking at the types it is pretty obvious why this couldn't work- however I'm relatively unsure if or how this could be resolved. As far as I get I couldn't implement BareB for Foo? Do "we" miss something like BareT?

Thanks in advance for any hint how to solve this and please let me know if I was unclear or could contribute further information.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions