nfrisby / invariant-functors

the 'invariant' Haskell package for invariant functors
BSD 2-Clause "Simplified" License
15 stars 10 forks source link

Applicative-like invariant #23

Closed nikita-volkov closed 3 years ago

nikita-volkov commented 3 years ago

Many invariant functors can be composed as products. Think about an abstraction like Codec a for binary serialisation. To be able to compose a codec of a product value from codecs of its components, such a class will come in handy.

What do you think?

-- |
-- Combination of 'Divisible' and 'Applicative'
-- providing the ability to combine invariant functors.
--
-- The inherited 'Pointed' instance provides
-- the identity operation.
-- Think of it as a comination of 'conquer' and 'pure'.
class (Invariant f, Pointed f) => ProductInvariant f where
  invmapBoth ::
    -- | Dissect contravariantly.
    (c -> (a, b)) ->
    -- | Combine covariantly. 'liftA2'-style.
    (a -> b -> c) ->
    f a ->
    f b ->
    f c

BTW, I am not sure whether this design is correct or optimal yet.

nikita-volkov commented 3 years ago

Here's the example in details:

-- Given a product type:
data Credentials = Credentials Username Password

-- And codecs for its components:
usernameCodec :: Codec Username
passwordCodec :: Codec Password

-- A codec for the product type can be constructed by composition:
credentialsCodec :: Codec Credentials
credentialsCodec =
  invmapBoth dissect combine usernameCodec passwordCodec
  where
    dissect (Codec a b) = (a, b)
    combine = Codec
RyanGlScott commented 3 years ago

The topic has come up before in #10. At the time, there were a number of questions that we couldn't come up with satisfactory answers for. Namely, I wasn't sure what names to give it (there wasn't anything readily available from existing literature to name it after), it was unclear what laws such a class should have, and it was also unclear if this sort of thing was actually common enough to warrant packaging up into its own class. I didn't feel qualified to answer all of those questions, so I gave up.

In short, I wouldn't say I'm diametrically opposed to adding such a class, but I am skeptical.

nikita-volkov commented 3 years ago

I see. I'll have it closed for now.

endgame commented 3 years ago

This might also be worth reading; I gave up for similar reasons to @RyanGlScott: http://jackkelly.name/blog/archives/2020/08/19/abstracting_over_applicative_alternative_divisible_and_decidable/index.html

I wound up being more interested in building operations that work on profunctors instead: https://github.com/tomjaguarpaw/product-profunctors/pull/59