每个重复嵌套的 monad 都有用吗?

Dan*_*Dos 6 io monads haskell

通过标题,我的意思是像Monad m => m (m a).

当 monad 的结构很简单时,我很容易想到这种类型的用法:

  • [[a]],这是一个多维列表

  • Maybe (Maybe a),这是一种由两个错误状态邻接的类型

  • Either e (Either e a),就像上面一样,但是有消息

  • Monoid m => (m,(m,a)),这是一个 writer monad,有两件事要写

  • r -> r -> a,这是一个 reader monad,有两个东西可以读取

  • Identity (Identity a),这仍然是身份 monad

  • Complex (Complex a),这是一个 2×2 矩阵

但是,如果我考虑以下类型,我的脑海中就会出现混乱:

  • ReadP (ReadP a)? 为什么它ReadP不是 的实例时会有用Read

  • ReadPrec (ReadPrec a)? 像上面那样?

  • Monad m => Kleisli m a (Kleisli m a b)?

  • IO (IO a)!?这一定有用。想一想实在是太难了。

  • forall s. ST s (ST s a)!?这应该像上面那样。

这些类型有实际用途吗?尤其是那个IO

再想一想,我可能需要随机选择一个IO动作。这是一个IO (IO a)专注于输入的例子。一个专注于输出的人呢?

prz*_*_li 0

不要紧。

单子之所以是单子,正是因为 Monad ( Monad a )我们总能得到Monad a。这种操作称为“连接”,它是“绑定”的替代操作,可以形成 Monad 的定义。Haskell 使用“bind”,因为它对于编写一元代码更有用:)(连接可以用绑定实现,绑定可以用连接实现 - 它们是等效的)

不要紧

这实际上是一个小谎言,因为形成能力Monad ( Monad a )实际上也是单子成为单子的一部分。Monad (Monad a)在某些行动中作为过渡代表。

完整的答案是:是的,因为这可以启用 Monad。虽然当Monad ( Monad a )您为某些 Monad 列出时可以有额外的“域”含义;)