【问题标题】:Haskell. Why it is working? (Iteration over Monad)哈斯克尔。为什么它在工作? (对 Monad 的迭代)
【发布时间】:2015-12-09 12:52:16
【问题描述】:
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。我在这里缺少什么?

【问题讨论】:

  • >>=[] 的定义就是concatMap——这个函数就是做映射的。
  • 你已经使用单子定律定义了fmap
  • 我不是第一次发现>>= 在这种情况下令人困惑。这里与 Monads 无关。
  • @ vikingsteve 我猜 list [] 是一个单子。这就是为列表定义 >>= 的原因。

标签: haskell io-monad


【解决方案1】:

m 这里是[]liftMM 通过委托(>>=)returnm 的实现而工作。因此,您需要了解(>>=)return 的列表,如果您查看definition,它们是:

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

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

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

【讨论】:

    【解决方案2】:

    列表是monad,因此给定地图的签名:

    map :: (a-&gt;b) -&gt; [a] -&gt; [b]

    以及 liftMM 的签名

    liftMM :: Monad m =&gt; (a -&gt; b) -&gt; m a -&gt; m b

    []m

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

    【讨论】:

      猜你喜欢
      • 2015-01-01
      • 2013-07-30
      • 2010-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多