在我使用=>
而非->
的错误收到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}} - 这不是我想要的。
请给我一个如何实现此功能的提示。
答案 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
。