1
liftMM :: Monad m => (a -> b) -> m a -> m b
liftMM f m = m >>= \a -> return (f a)

我跑:

> liftMM (*2) [1..10]

我得到了输出:

> [2,4,6,8,10,12,14,16,18,20]

我看不到这个函数是如何映射所有列表的值的?没有任何递归或迭代,只需将 monad 内部 m 值传递给函数 f。我在这里缺少什么?

4

2 回答 2

2

m这里是[]并且liftMM通过委派(>>=)returnfor的实现来工作m。因此,您需要了解(>>=)return对于列表,如果您查看它们的定义,它们是:

instance Monad []  where
    xs >>= f            = [y | x <- xs, y <- f x]
    return x            = [x]

所以对于源列表中的每个元素都>>=适用f,然后将返回列表的每个元素插入到结果列表中。

return x只返回一个包含x所以return (f a)返回一个列表的单例列表[f a]。然后将这些单个元素列表中的每一个组合起来(>>=)以创建输出列表。

于 2015-12-09T13:07:15.387 回答
0

列表是 a monad,因此给定 map 的签名:

map :: (a->b) -> [a] -> [b]

和 liftMM 的签名

liftMM :: Monad m => (a -> b) -> m a -> m b

[]m

这意味着对于列表 liftMMmap做同样的事情。

于 2015-12-09T12:55:44.380 回答