Haskell。为什么它有效? (迭代 Monad)
Haskell. Why it is working? (Iteration over Monad)
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。我在这里缺少什么?
列表是 monad
,因此给定地图的签名:
map :: (a->b) -> [a] -> [b]
和 liftMM 的签名
liftMM :: Monad m => (a -> b) -> m a -> m b
[]
是 m
这意味着 for lists liftMM
和 map
做同样的事情。
m
这里是 []
和 liftMM
通过委派 (>>=)
和 return
的实现来实现 m
。因此,您需要了解列表的 (>>=)
和 return
,如果您查看 definition,它们是:
instance Monad [] where
xs >>= f = [y | x <- xs, y <- f x]
return x = [x]
因此对于源列表中的每个元素 >>=
应用 f
然后将返回列表的每个元素插入到结果列表中。
return x
只是 returns 一个包含 x
的单例列表,所以 return (f a)
returns 一个列表 [f a]
。然后 (>>=)
组合这些单个元素列表中的每一个以创建输出列表。
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。我在这里缺少什么?
列表是 monad
,因此给定地图的签名:
map :: (a->b) -> [a] -> [b]
和 liftMM 的签名
liftMM :: Monad m => (a -> b) -> m a -> m b
[]
是 m
这意味着 for lists liftMM
和 map
做同样的事情。
m
这里是 []
和 liftMM
通过委派 (>>=)
和 return
的实现来实现 m
。因此,您需要了解列表的 (>>=)
和 return
,如果您查看 definition,它们是:
instance Monad [] where
xs >>= f = [y | x <- xs, y <- f x]
return x = [x]
因此对于源列表中的每个元素 >>=
应用 f
然后将返回列表的每个元素插入到结果列表中。
return x
只是 returns 一个包含 x
的单例列表,所以 return (f a)
returns 一个列表 [f a]
。然后 (>>=)
组合这些单个元素列表中的每一个以创建输出列表。