Aqui está o post que eu vou me referir . Além disso, vou usar os mesmos trechos do OP nessa pergunta para não separar os materiais .
É sabido que uma ArrowApply
instância produz uma Mônada e vice-versa:
newtype ArrowMonad a b = ArrowMonad (a () b)
instance Arrow a => Functor (ArrowMonad a) where
fmap f (ArrowMonad m) = ArrowMonad $ m >>> arr f
instance Arrow a => Applicative (ArrowMonad a) where
pure x = ArrowMonad (arr (const x))
ArrowMonad f <*> ArrowMonad x = ArrowMonad (f &&& x >>> arr (uncurry id))
instance ArrowApply a => Monad (ArrowMonad a) where
ArrowMonad m >>= f = ArrowMonad $
m >>> arr (\x -> let ArrowMonad h = f x in (h, ())) >>> app
newtype Kleisli m a b = Kleisli { runKleisli :: a -> m b }
instance Monad m => Category (Kleisli m) where
id = Kleisli return
(Kleisli f) . (Kleisli g) = Kleisli (\b -> g b >>= f)
instance Monad m => Arrow (Kleisli m) where
arr f = Kleisli (return . f)
first (Kleisli f) = Kleisli (\ ~(b,d) -> f b >>= \c -> return (c,d))
second (Kleisli f) = Kleisli (\ ~(d,b) -> f b >>= \c -> return (d,c))
E até me deparar com o post mencionado acima, senti que esse trecho era uma prova plausível da equivalência de ArrowApply
e Monad
classes. No entanto, ter o conhecimento de que Arrow e Applicative não são, de fato, equivalentes e o seguinte snippet me deixou curioso sobre a prova completa da equivalência de Monad
e ArrowApply
:
newtype Arrplicative arr o a = Arrplicative{ runArrplicative :: arr o a }
instance (Arrow arr) => Functor (Arrplicative arr o) where
fmap f = Arrplicative . (arr f .) . runArrplicative
instance (Arrow arr) => Applicative (Arrplicative arr o) where
pure = Arrplicative . arr . const
Arrplicative af <*> Arrplicative ax = Arrplicative $
arr (uncurry ($)) . (af &&& ax)
newtype Applicarrow f a b = Applicarrow{ runApplicarrow :: f (a -> b) }
instance (Applicative f) => Category (Applicarrow f) where
id = Applicarrow $ pure id
Applicarrow g . Applicarrow f = Applicarrow $ (.) <$> g <*> f
instance (Applicative f) => Arrow (Applicarrow f) where
arr = Applicarrow . pure
first (Applicarrow f) = Applicarrow $ first <$> f
> Assim, se você viaja através do aplicativo, perde alguns recursos.
É óbvio que, se os exemplos forem fornecidos, ainda não entendi como o "round-trip" através do Monad preserva todos os recursos ArrowApply, pois inicialmente tínhamos uma seta que depende de alguma entrada ( a b c
), mas no final, acabamos com uma seta forçada a um invólucro que tem o tipo de unidade como seu tipo de entrada ( ArrowMonad (a () b)
).
É óbvio que estou fazendo algo terrivelmente errado aqui, mas não consigo entender exatamente o que.
Qual é a prova completa de que ArrowApply
e Monad
são equivalentes?
Quais são os exemplos de desigualdade Arrow
e Applicative
explicação? Um generaliza outro?
Qual é a interpretação de toda essa situação no cálculo de flechas e na teoria das categorias?
Apreciaria explicações e dicas completas que poderiam ajudar a elaborar uma prova plausível de si mesmas.