【问题标题】:Why does the list monad work when no function is provided [duplicate]为什么不提供功能时列表单子起作用[重复]
【发布时间】:2019-05-16 11:31:48
【问题描述】:

当没有指定函数时,我试图了解列表 monad:

func::[(Int,String)]
func =do
    a <- [1,2,3]
    b <- ["a","b"]
    return (a,b)

我知道(&gt;&gt;=) ml f=concat (map f ml)。那么在我们的例子中f 的值是多少?
当我说 : a&lt;-[1,2,3] 会被翻译成[1,2,3]&gt;&gt;=(\x-&gt;return x)
如果不是,为什么它不会崩溃,因为我没有为绑定运算符提供任何功能?

稍后编辑

感谢您的回复,虽然我了解多个 &gt;&gt;= 会发生什么,但我更关心这个简单的场景:

    mym =do
     a<-[1,2,3]
     return a

什么是等价物? [1,2,3] &gt;&gt;= (\x -&gt; return x)

【问题讨论】:

  • 是的,[1,2,3] &gt;&gt;= (\x -&gt; return x) 在您的编辑中是正确的。
  • 或者干脆[1,2,3] &gt;&gt;= return
  • 根据 Monad 定律,这就是 [1,2,3]

标签: list haskell monads


【解决方案1】:

为绑定函数提供了一个函数。如果我们desugar the do notation [Haskell'10 report],我们会得到:

[1,2,3] &gt;&gt;= (\a -&gt; ["a", "b"] &gt;&gt;= (\b -&gt; return (a, b)))

这意味着我们在这里基本上得到:

concatMap (\a -&gt; ["a", "b"] &gt;&gt;= (\b -&gt; return (a, b))) [1,2,3]

一个 因此:

concatMap (\a -&gt; concatMap (\b -&gt; [(a, b)]) ["a", "b"]) [1,2,3]

所以我们用给定的函数map[1,2,3],然后对于每个元素a,我们用concatMap 执行第二个\b -&gt; [(a, b)]。一个concatMap,其中每个元素都映射到一个单例元素,相当于一个map,所以:

concatMap (\a -&gt; map (\b -&gt; (a, b)) ["a", "b"]) [1,2,3]

相当于:

concatMap (\a -&gt; [(a, "a"), (a, "b")]) [1,2,3]

因此:

[(1, "a"), (1, "b"), (2, "a"), (2, "b"), (3, "a"), (3, "b")]

所以窗帘后面的do 块会产生一个表达式。

EDIT[1,2,3] &gt;&gt;= (\x -&gt; return x) 的等价物是:

concatMap (\x -> [x]) [1,2,3]

因为(&gt;&gt;=) 与列表单子只是flip concatMap,而return\x -&gt; [x]。因此,我们在这里将一个元素包装在一个列表中,然后连接这些列表。因此这相当于:

map id [1,2,3]

因此相当于:

[1,2,3]

【讨论】:

    【解决方案2】:
    do
    a <- [1,2,3]
    b <- ["a","b"]
    return (a,b)
    

    被翻译成

    [1,2,3] >>= (\a -> do
      b <- ["a","b"]
      return (a,b) )
    

    翻译成

    [1,2,3] >>= (\a ->
      ["a","b"] >>= (\b ->
         return (a,b) ))
    

    基本上ml &gt;&gt;= f 中的f 函数是“do 块的其余部分”。 a &lt;- [1,2,3] 没有独立的翻译,在其 do 块中只有一个。

    你可以尝试简化上面的表达式,直到你得到

    [1,2,3] >>= (\a ->
      ["a","b"] >>= (\b ->
         [(a,b)] ))
    

    然后

    [1,2,3] >>= (\a ->
      [(a, "a"), (a, "b")])
    

    然后

    [(1, "a"), (1, "b"), (2, "a"), (2, "b"), (3, "a"), (3, "b")]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-10
      • 1970-01-01
      • 2019-03-08
      • 1970-01-01
      • 1970-01-01
      • 2017-12-22
      相关资源
      最近更新 更多