【问题标题】:Equivalence of (M a >>= f) >>= g and M a >>= (f >>= g) in HaskellHaskell 中 (M a >>= f) >>= g 和 M a >>= (f >>= g) 的等价性
【发布时间】:2016-07-28 02:33:09
【问题描述】:

我有两个等效的 Haskell 函数。

triple :: Int -> Int
triple = do
  n <- id
  d <- (n+)
  (d+)

triple2 :: Int -> Int  
triple2 = (id >>= (\n -> (n+))) >>= (\d -> (d+))    

&gt;&gt;=的签名是M a -&gt; (a -&gt; M b) -&gt; M b,所以括号用来强调((Ma &gt;&gt;= f) &gt;&gt;= f2)M b &gt;&gt; f2的关系。

不过,这个triple3 也是和triple 或triple2 等价的函数。

triple3 :: Int -> Int  
triple3 = id >>= (\n -> (n+) >>= (\d -> (d+)))

这些等价背后的逻辑是什么?

【问题讨论】:

  • 在没有任何问题的情况下投票否决问题有什么问题?我没想到会从 Haskell 标记的问题中看到这种怯懦。

标签: haskell monads


【解决方案1】:

这种等价是Monad Laws 的第三个,并且与关联性有关,因此triple2triple3 是等价的也就不足为奇了。毕竟(-&gt;) r monad 遵守单子法则。第三个单子定律指出

(m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)

在您的情况下,您有 m = idf = \n -&gt; (n+)g = \d -&gt; (d+)。为了证明这个定律为什么成立,我们需要看看definition of (&gt;&gt;=) for this monad。从这个链接,我们得到了

f >>= k = \ r -> k (f r) r

要使用 (&gt;&gt;=) 的定义验证第三个单子定律,我们将使用几个规则:

现在证明:

(m >>= f) >>= g
  ≡ (\ r1 -> f (m r1) r1) >>= g                             (Definition of (>>=))
  ≡ \ r2 -> g ((\ r1 -> f (m r1) r1) r2) r2                 (Definition of (>>=))
  ≡ \ r2 -> g (f (m r2) r2) r2                              (Beta transformation)
  ≡ \ r2 -> g ((f (m r2)) r2) r2                            (Function currying)
  ≡ \ r2 -> (\ r1 -> g ((f (m r2)) r1) r1) r2               (Beta transformation)
  ≡ \ r2 -> ((\ x -> (\ r1 -> g ((f x) r1) r1)) (m r2)) r2  (Beta transformation)
  ≡ \ r2 -> ((\ x -> f x >>= g) (m r2)) r2                  (Definition of (>>=)) 
  ≡ \ r2 -> (\ x -> f x >>= g) (m r2) r2                    (Function currying) 
  ≡ m >>= (\ x -> f x >>= g)                                (Definition of (>>=))  

【讨论】:

    猜你喜欢
    • 2019-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    相关资源
    最近更新 更多