Сюда.
Фольклор в том, что у нас может быть моноидальный функтор в Хаскеле .
Например, я могу предложить это определение:
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
? Или это все неправильно с самого начала?