Selon la Typeclassopedia (entre autres sources), Applicative
se situe logiquement entre Monad
y Pointed
(et donc Functor
) dans la hiérarchie des classes de types, de sorte que nous aurions idéalement quelque chose comme ceci si le prélude Haskell était écrit aujourd'hui :
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Pointed f where
pure :: a -> f a
class Pointed f => Applicative f where
(<*>) :: f (a -> b) -> f a -> f b
class Applicative m => Monad m where
-- either the traditional bind operation
(>>=) :: (m a) -> (a -> m b) -> m b
-- or the join operation, which together with fmap is enough
join :: m (m a) -> m a
-- or both with mutual default definitions
f >>= x = join ((fmap f) x)
join x = x >>= id
-- with return replaced by the inherited pure
-- ignoring fail for the purposes of discussion
(où ces définitions par défaut ont été retapées par moi à partir de la base de données de l'UE). explication à Wikipedia (les erreurs étant de mon fait, mais s'il y a des erreurs, c'est au moins en principe possible).
Comme les bibliothèques sont actuellement définies, nous avons :
liftA :: (Applicative f) => (a -> b) -> f a -> f b
liftM :: (Monad m) => (a -> b) -> m a -> m b
et :
(<*>) :: (Applicative f) => f (a -> b) -> f a -> f b
ap :: (Monad m) => m (a -> b) -> m a -> m b
Notez la similitude entre ces types au sein de chaque paire.
Ma question est la suivante : est-ce que liftM
(à distinguer de liftA
) et ap
(à distinguer de <*>
), simplement le résultat de la réalité historique que Monad
n'a pas été conçu avec Pointed
y Applicative
en tête ? Ou sont-elles d'une autre manière comportementale (potentiellement, pour certains aspects légaux Monad
) distinctes des versions qui ne requièrent qu'une Applicative
contexte ?
S'ils sont distincts, pourriez-vous fournir un ensemble de définitions simples (obéir aux lois exigées de Monad
, Applicative
, Pointed
y Functor
décrites dans la Typeclassopedia et ailleurs mais non appliquées par le système de types) pour lesquelles liftA
y liftM
se comportent-ils différemment ?
Sinon, si elles ne sont pas distinctes, pourriez-vous prouver leur équivalence en utilisant ces mêmes lois comme prémisses ?