实现 `distrib` 函数

Implementing `distrib` Function

在我使用 => 而不是 -> 的错误中得到 之后,我正在尝试实施 distrib:

distrib :: (Monad m, Monad n) => n (m a) -> m (n a)
distrib x = do xx <- x
               return xx 

但是,鉴于编译时错误,这不起作用:

Expected type: m (m a)
  Actual type: n (m a)

我意识到使用 do 符号是行不通的,因为在调用 xx <- x 时,预期的 return 类型(do 块)是 x,即 n (m a) - 这不是我想要的。

请指点一下如何实现这个功能。

不能为两个任意的 monad 编写此函数,但当外部类型为 Traversable 时它确实存在,因为一些(但不是全部)Monad 实例是:

sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)

然后您可以定义

distrib :: (Monad m, Traversable m, Monad n) => m (n a) -> n (m a)
distrib = sequence

但这不会给你带来任何好处,所以你不妨在适当的时候使用 sequence