实现`distrib`功能

Kev*_*ith 0 monads haskell

在获得了我使用的错误的帮助=>而不是->,我正在尝试实现distrib:

distrib :: (Monad m, Monad n) => n (m a) -> m (n a)
distrib x = do xx <- x
               return xx 
Run Code Online (Sandbox Code Playgroud)

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

Expected type: m (m a)
  Actual type: n (m a)
Run Code Online (Sandbox Code Playgroud)

我意识到使用do符号将无法工作,因为在调用时xx <- x,(do块的预期返回类型)是x,即n (m a)- 这不是我想要的.

请给我一个如何实现这个功能的提示.

Rei*_*chs 8

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

sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
Run Code Online (Sandbox Code Playgroud)

然后你可以定义

distrib :: (Monad m, Traversable m, Monad n) => m (n a) -> n (m a)
distrib = sequence
Run Code Online (Sandbox Code Playgroud)

但这并没有给你买任何东西,所以你也可以sequence在适当的时候使用.