Mi piacerebbe avere una funzione per mappare una funzione pura in un contenitore o sequenziare un'azione applicativa/monadica attraverso di essa. Per la mappatura pura abbiamoIl functor è per (a -> b) -> (f a -> f b), a cosa serve (Categoria c) => c a b -> c (f a) (f b)?
fmap :: Functor f => (a -> b) -> (f a -> f b)
per il sequenziamento monadica abbiamo (da Data.Taversable)
mapM :: (Traversable f, Monad m) => (a -> m b) -> (f a -> m (f b))
che è simile a
mapKleisli :: (Traversable f, Monad m) => Kleisli m a b -> Kleisli m (f a) (f b)
mapKleisli = Kleisli . mapM . runKleisli
Sappiamo entrambi (->) e (Kleisli m) sono categorie (e frecce). Quindi è naturale fare una generalizzazione:
mapCategory :: (X f, Category c) => c a b -> c (f a) (f b)
Conosci una classe X con un metodo simile? Forse, da qualche parte in hackage? Ho provato a hoogle/hayoo ma non ho trovato nulla di appropriato.
Aggiornamento:
Ora so meglio quello che mi serve. Sia le frecce di Kleisli che (->) sono istanze di ArrowApply che è potente quanto Monad. Sono venuto con questa versione freccia a base di Travesable:
{-# LANGUAGE TypeOperators #-}
import Prelude hiding (id, (.), mapM)
import Control.Arrow
import Control.Category
class Traversable f where
traverse :: ArrowApply (~>) => f a -> (a ~> b) ~> f b
mapArrow :: (ArrowApply (~>), Traversable f) => a ~> b -> f a ~> f b
mapArrow a = arr (\x -> (traverse x, a)) >>> app
instance Traversable Maybe where
traverse Nothing = arr (const Nothing)
traverse (Just x) = arr (\a -> (a, x)) >>> app >>> arr Just
instance Traversable [] where
traverse [] = arr (const [])
traverse (x : xs) = undefined -- this is hard!
ho potuto utilizzare solo solita applicativa basata Traversable, con identità per funzioni pure, ma non sono sicuro che sia buono. Considerare le funzioni pure come caso speciale di azioni monadiche è strano. Interpretare sia le funzioni pure che le azioni monadiche come istanze di alcune classi di azione (Categoria/Freccia/ArrowApply) mi sembra più semplice.
Domande: desideri terminare l'istanza per []
? La mia opinione su ArrowApply vs Monad ha qualche senso?
Grazie per la risposta, ma in questo caso ho più interesse pratico che teorico. [Nel pacchetto categorie] (http://hackage.haskell.org/packages/archive/categories/0.56.0/doc/html/Control-Categorical-Functor.html) abbiamo solo istanze di Functor (Endo) per la categoria (->) che non ci fornisce nulla di nuovo rispetto a ciò che abbiamo nella base (eccetto la classe stessa). – modular
@ user713303: sei libero di scrivere le tue istanze. Ad esempio, sarebbe molto semplice farlo per le frecce di Kleisli, come hai dimostrato nella tua domanda. –
Infatti, se hai in mente esempi pratici e utili, perché non li contribuisci? Ecco [la pagina github] (https://github.com/ekmett/categories) per il pacchetto. –