2015-04-15 113 views
0

上我曾经=>而不是->错误得到help后,我试图实现distrib实现`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,即n (m a) - 这不是我想要的。

请给我一个关于如何实现这个功能的提示。

+11

给出的类型没有实现。例如,'IO(Maybe a) - > Maybe(IO a)'可以让我们找到一些关于'IO'动作返回而不运行的信息。你需要更多的关于'm'和'n'。 [This](http://stackoverflow.com/questions/7040844/applicatives-compose-monads-dont)可能是一个有趣的线程。 – luqui

+0

呃等我的意思是[这个线程](http://stackoverflow.com/questions/29453915/composing-monads-v-applicative-functors/29454112#29454112) – luqui

+2

请参阅[具体的例子显示monad没有在合成下关闭与证明)?](http://stackoverflow.com/q/13034229/1333025)。 –

回答

8

此功能不能用于任意两个单子写,但是当外类型为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