Могу ли я инвертировать Аппликатив? - PullRequest
1 голос
/ 19 октября 2019

Сюда.

Фольклор в том, что у нас может быть моноидальный функтор в Хаскеле .

Например, я могу предложить это определение:

class Functor f => Monoidal f where

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

Одним из возможных производных Monoidal из Applciative является экземпляр Bitraversable для кортежей:

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

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

Я также могу восстановить метод определения Applicative вот так: (хотя я не уверен, правильно ли это в отношении законов.)

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

Есть и другие функции, которые я могу определить, например, через coherence:

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

Итак, теперь я хотел бы иметь такие же приятные вещи, которые были у меня выше с Monoidal, но наоборот:

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

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

Я пришелс одним возможным определением 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

- Но это не выглядит слишком похоже на определение ap, которое я предложил выше, такЯ все еще подозрительна.

С deap У меня вообще не было удачи. Одна из причин заключается в том, что применение функции обычно нельзя отменить.

???

Как я могу продолжить эту строку запроса? Есть ли когда-нибудь определение deap? Или это все неправильно с самого начала?

...