到目前为止,我遇到的每个monad(可以表示为数据类型)都有相应的monad变换器,或者可以有一个.有这样一个不能有一个单子吗?或者所有monad都有相应的变压器?
通过对应于monad的变换器t,m我的意思t Identity是同构的m.当然,它满足monad变压器法则,并且t n是任何monad的monad n.
我希望看到每个monad都有一个证明(理想情况下是建设性的证明),或者没有一个证明(带证明)的特定monad的例子.我对更多面向Haskell的答案以及(类别)理论答案感兴趣.
作为后续问题,是有一个单子m是有两个不同的变压器t1和t2?也就是说,t1 Identity同构t2 Identity和m,但有一个单子n这样t1 n是不是同构t2 n.
(IO并且ST有一个特殊的语义,所以我不在这里考虑它们,让我们完全忽略它们.让我们只关注可以使用数据类型构造的"纯"monad.)
我最近偶然发现了 Kleisli 的概念,我阅读的每个教程/链接/参考都通过以下结构激发了 Kleisli 的使用:
f: a -> m[b]with g: b -> m[c]- 我认为monad 的定义已经捕捉到了这种情况 -do/bind/for/flatMap这样做。人们不必依靠 Kleisli 构造来实现这一目标。所以这不可能是 Kleisli IMO 的“主要”用例。Config 注入,则可以使用 Kleisli 构造来抽象出可重复注入。有很多方法可以实现这一点(例如implicit在 Scala 中使用s),可能不需要调用 Kleisli。同样,IMO 这并没有作为“主要”用例脱颖而出。M1[M2[M1[M2[a]]]],可以转化成[M1[M2[a]]]其可(I可能是错误的)来跨越一元边界压扁是可组合与a -> M3[b](比方说)。为此,我们可以使用 Kleisli 三元组并调用该构造,因为如果您要从头开始,您可能会重新发明Kleisli。这似乎是证明使用 Kleisli 合理的一个很好的候选者。这样对吗? …如果我有两个单子m和n,和n是穿越,我一定有复合m-over- n单子?
更正式的,这就是我的想法:
import Control.Monad
import Data.Functor.Compose
prebind :: (Monad m, Monad n) =>
         m (n a) -> (a -> m (n b)) -> m (n (m (n b)))
mnx `prebind` f = do nx <- mnx
                     return $ do x <- nx
                                 return $ f x
instance (Monad m, Monad n, Traversable n) => Monad (Compose m n) where
  return = Compose . return . return
  Compose mnmnx >>= f …为什么没有monad实例Control.Applicative.Const?以下定义是正确的,还是违反了monad法则?  
instance Monoid a => Monad (Const a) where
  return _ = Const mempty
  (Const x) >>= _ = Const x
你能想到任何有用的应用吗?
我对这里描述的用于确定伴随仿函数的monad变换器的结构很感兴趣.这里有一些代码总结了基本思想:
{-# LANGUAGE MultiParamTypeClasses #-}
import           Control.Monad
newtype Three g f m a = Three { getThree :: g (m (f a)) }
class (Functor f, Functor g) => Adjoint f g where
  counit :: f (g a) -> a
  unit   :: a -> g (f a)
instance (Adjoint f g, Monad m) => Monad (Three g f m) where
  return  = Three . fmap return . unit
  m >>= f = Three $ fmap (>>= counit . …