Jusqu'à présent, chaque monade (qui peut être représentée comme un type de données) que j'ai rencontrée avait un transformateur de monade correspondant, ou pouvait en avoir un. Existe-t-il une monade qui ne peut pas en avoir ? Ou toutes les monades ont-elles un transformateur correspondant ?
Par un transformateur t
correspondant à la monade m
Je veux dire que t Identity
est isomorphe à m
. Et bien sûr qu'il satisfait aux lois du transformateur de monades et que t n
est une monade pour toute monade n
.
J'aimerais voir soit une preuve (idéalement constructive) que chaque monade en a une, soit un exemple d'une monade particulière qui n'en a pas (avec une preuve). Je suis intéressé par des réponses plus orientées vers Haskell, ainsi que par des réponses théoriques (de catégorie).
En guise de question complémentaire, existe-t-il une monade m
qui a deux transformateurs distincts t1
y t2
? C'est-à-dire, t1 Identity
est isomorphe à t2 Identity
et à m
mais il existe une monade n
tal que t1 n
n'est pas isomorphe à t2 n
.
( IO
y ST
ont une sémantique particulière, je ne les prends donc pas en compte ici et ignorons-les complètement. Concentrons-nous uniquement sur les monades "pures" qui peuvent être construites à l'aide de types de données).
5 votes
ST
est l'autre exemple évident, mais il viole également votre restriction de monade "pure".0 votes
Donc vous cherchez un type T tel qu'il y a un
instance Monad (T Identity)
qui satisfait aux lois des monades, mais tel que T ne satisfait pas aux lois des transformateurs de monades ?0 votes
@GaneshSittampalam Bon point, j'ai ajouté
ST
à la "liste d'exclusion".2 votes
@bennofs Oui, mais pas seulement les lois du transformateur de monade, ça pourrait être que
T
les satisfait, mais pour une certaine monaden
le typeT n
n'est pas une monade. Par exempleListT
ne satisfait pas aux lois des monades pour certaines monades seulement (non commutatives), cependant, il existe un autre transformateur correct pour[]
.4 votes
La liste des exceptions "c'est évidemment IO" est pratiquement infinie. Il y a
STM
par exemple. Mais il y a aussi toutes les monades personnalisées qui fonctionnent intrinsèquement sur IO. De nombreuses bibliothèques fournissent de telles choses.0 votes
Il est amusant de constater qu'il est très difficile de trouver un transformateur de monade trivial.
0 votes
Le "lecteur double duel"
(a -> b) -> b
pourrait être un candidat libre d'IO (a-t-il un nom standard / une implémentation, BTW) ?0 votes
@leftaroundabout
Cont
?1 votes
@Rhymoid
newtype Id1 m a = Id1 (m a)
?2 votes
@leftaroundabout
Cont
est presque le contraire : Il est si facile de se transformer en transformateur que les méthodes de laMonad
instance pourContT m
n'ont même pas besoin de laMonad
instance pourm
.2 votes
J'ai l'impression qu'une définition précise de ce que cela signifie pour un type de "posséder une monade" est nécessaire. Pourquoi est-ce que list "a" à la fois ListT et ListTDoneRight ? Peut-on répondre à cette question en faisant appel à des transformateurs de monades libres ? Quelque chose comme
T
conMonad T
tal queT' Identity ~ T
mais il existe unn
conMonad n
tal queT' n
n'instancie plusMonad
ou tel queT'
n'est pasMonadTrans
. Il pourrait y avoir beaucoup de telsT'
cependant (comme le souligne ListT). Tous sont pris en considération pour chaque projetT
mais0 votes
Cela ne semble pourtant pas évident, car le problème est facile à résoudre. Au moins la partie transformateur :
data I a = I () a
est une monade, est isomorphe àI' Identity
pourdata I' m a = I' (m ()) a
. MaisI'
n'est certainement pas un transformateur de monade.9 votes
Toute monade qui peut être exprimée comme une monade libre pour un certain foncteur (ce qui est le cas de presque toutes les monades) : stackoverflow.com/questions/14641864/ ) devrait également bénéficier du transformateur de monades gratuit.
1 votes
@Cirdec C'est un très bon point. Si une monade peut être construite comme une monade libre d'un certain foncteur, alors le même foncteur peut être utilisé pour construire son transformateur de monade correspondant. Il semble donc que les seuls candidats soient des monades qui ne peuvent pas être construites de cette façon.
0 votes
@PetrPudlák : non-constructif, mais puisque toutes les monades peuvent être écrites en termes de
Cont
et nous savons comment faireContT
toutes les monades ont un transformateur correspondant.0 votes
@JohnL Je pense que la manière simple d'intégrer une monade dans
Cont
est isomorphe à l'utilisation deContT
comme un transformateur, et il n'y a alors plus de place pour faire le résultat de cette transformation encore une autre monade.0 votes
@J.Abrahamson Ce n'est pas ce que je voulais dire.
Id1 Id
est isomorphe àId
seulement. Je pensais àTT m
un transformateur correspondant à toutm
(pour toutes les monadesm
:TT m Id ~ m
etc.).0 votes
@Rhymoid Je ne vois pas en quoi cela diffère :
Id1 m ~ m
pour toutes les monades. Si vous voulez insérer uneId
là-dedans, vous pouvez regardernewtype Compose f g a = Compose (f (g a))
?0 votes
@J.Abrahamson :
Id1 m ~ m
n'est pas suffisant pour queId1
oId1 m
un transformateur correspondant àm
selon la définition de l'OP.0 votes
@JohnL Cela semble prometteur, pourriez-vous nous en dire plus ? Par exemple, comment pourrait-on exprimer
[]
en utilisantCont
(pasContT
) ?0 votes
@PetrPudlák Quelque chose comme
\xs -> ContT (\f -> Identity (xs >>= runIdentity . f)
yrunIdentity . ($ Identity . return) . runContT
?0 votes
Le point de @Cirdec (que j'ai abordé de manière indépendante en un duplicata ) signifie qu'il y a effectivement sont transformateurs de monades correspondant à
IO
yST s
bien que la correspondance ne puisse pas être exprimée complètement en Haskell. Je ne sais pas si ces constructions ont une valeur pratique.0 votes
@PetrPudlák Je pense avoir un exemple de monade avec deux transformateurs non équivalents. Mon exemple est la "monade de recherche".
S p
défini partype S p a = (a -> p) -> a
a un transformateurt1 n a = (n a -> p) -> n a
et un transformateurt2 n a = (a -> n p) -> n a
. Les deux transformateurs ontlift
. Aussi,t1 Identity
est isomorphe àt2 Identity
et àS p
. Cependant,t2
n'est pas functoriel dans la monade étrangèren
alors quet1
est. Voir aussi le point 5 récemment ajouté dans ma réponse ci-dessous.