我可以反转适用性吗?

到此为止。

It is folklore that we can have a monoidal functor in Haskell.

例如,我可以提供以下定义:

class Functor f => Monoidal f where

    coherence :: (f a, f b) -> f (a, b)

One possible derivation of Monoidal from Applciative is via the Bitraversable instance for tuples:

instance (Functor f, Applicative f) => Monoidal f where

    coherence :: Applicative f => (f a, f b) -> f (a, b)
    coherence = bisequence

I can also recover the defining method of Applicative like this: (Though I am not sure if it is correct with respect to the laws.)

ap :: Monoidal f => f (a -> b) -> f a -> f b
ap f = (fmap . uncurry) ($) . coherence . (f,)

There are other functions I may define through coherence, for example:

curryA :: Monoidal f => (f (a, b) -> f c) -> f a -> f b -> f c
curryA f = (fmap . fmap) (f . coherence) (,)

然后回来。

我们可以撤消这些操作吗?

class DeMonoidal f where

    decoherence :: f (a, b) -> (f a, f b)

在这方面,一些应用函子具有明显的逆函数,例如:

instance DeMonoidal Stream where

    decoherence = Stream.unzip

So, now I would like to have the same nice things I had above with Monoidal, but the other way around:

deap :: (f b -> f a) -> f (b -> a)
deap = ?

uncurryA :: DeMonoidal f => (f a -> f b -> f c) -> f (a, b) -> f c
uncurryA = ?

I came up with one possible definition of uncurryA:

contramap :: (a -> b) -> (b -> c) -> (a -> c)
contramap f g = (g . f)

uncurryA :: DeMonoidal f => (f a -> f b -> f c) -> f (a, b) -> f c
uncurryA f = (contramap decoherence . uncurry) f

— But it does not look too similar to the definition of ap I have offered above, so I am yet suspicious.

With deap I did not have any luck at all. One reason is that function application cannot generally be reversed.

???

How can I proceed with this line of inquiry? Is there ever a definition of deap? Or is it all wrong from the very beginning?