在Haskell中编写嵌套的Monads

时间:2015-10-17 16:52:43

标签: haskell monads

有没有办法为嵌套monad实现bind?我想要的是以下签名:

.factory('JMGoogleMaps', function ($cordovaGeolocation) {

var fac = {};

fac.users = ['John', 'James', 'Jake']; 

return fac;

看起来它应该是一项微不足道的任务,但我不知何故不能绕过它。在我的程序中,我将这种模式用于monad的几种不同组合,对于每种组合,我都可以实现它。但对于一般情况,我只是不理解它。

编辑:在一般情况下似乎不可能。但在某些特殊情况下肯定是可能的。例如。如果内在的Monad是一个可能。因为我想要使用的所有Monads都可以使用,所以有额外的限制似乎对我来说很好。所以我稍微改变了一下这个问题:

我需要对n进行哪些额外限制,以便可以进行以下操作?

(>>>=) :: (Monad m, Monad n) => m (n a) -> (a -> m (n b)) -> m (n b)

1 个答案:

答案 0 :(得分:7)

扩展评论:正如linked questions所示,有必要让某些函数n (m a) -> m (n a)甚至有机会使合成成为monad。

如果您的内部monad是Traversable,那么sequence会提供这样的功能,而以下内容将具有正确的类型

(>>>=) :: (Monad m, Monad n, Traversable n) => m (n a) -> (a -> m (n b)) -> m (n b)
m >>>= k = do
    a <- m
    b <- sequence (map k a)
    return (join b)

几个众所周知的变换器实际上是简单的newtype包装器,而不是与此类似的东西(虽然主要是使用模式匹配来定义事物而不是使用内部monad'MonadTraversable实例):< / p>

  • MaybeT基于Maybe
  • ExceptT基于Either
  • WriterT基于(,)(,)通常没有定义Monad个实例, WriterT正在使用错误的元组命令,如果有的话,可以使用它 - 但在精神方面它可能有。)
  • ListT基于[]。哦,哎呀 ......

最后一个事实上是因为是monad而臭名昭着,除非被提升的monad是“可交换的” - 否则,monad法则应该相等的表达可以给出不同的效果顺序。我的预感是,这主要来自于能够包含多个值的列表,这与其他可靠的工作示例不同。

所以,虽然上面的定义是正确的类型,但它仍然可以打破monad法则。

另外,作为事后的想法,另一个变换器是这样一个嵌套的monad,但是以完全不同的方式:ReaderT,基于使用(->)作为外部 monad。