实现`distrib`功能

时间:2015-04-15 19:32:19

标签: haskell monads

在我使用=>而非->的错误收到help后,我正在尝试实施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时,do块的预期返回类型为x,即{ {1}} - 这不是我想要的。

请给我一个如何实现此功能的提示。

1 个答案:

答案 0 :(得分:8)

此函数不能为两个任意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