簡體   English   中英

monad的“ap”實現有多武斷?

[英]How arbitrary is the “ap” implementation for monads?

我目前正在研究monad和applicative functors之間的聯系。

我看到ap的兩個實現:

ap m1 m2 = do { f <- m1 ; x <- m2 ; return (f x) }

ap m1 m2 = do { x <- m2 ; f <- m1 ; return (f x) }

第二個是不同的,但它是<*>的良好實現嗎?

我迷失了pure (.) <*> u <*> v <*> w = u <*> (v <*> w)的證明pure (.) <*> u <*> v <*> w = u <*> (v <*> w)

我試圖直觀地說“monad的哪一部分是應用函子”......

這個問題至少有三個相關方面。

  1. 給定一個Monad m實例,其必要的Applicative m超類實例的規范是什么? purereturn<*>ap ,所以

     mf <*> ms == do f <- mf; s <- ms; return (fs) 

請注意,本規范不是Applicative類的法律。 這是Monad的要求,以確保一致的使用模式。

  1. 由於規格(由候選人的實現),是ap的唯一可接受的實施。 答案 :響亮, 沒有 >>=類型允許的值依賴性有時會導致執行效率低下:有些情況可以使<*>ap更有效,因為你不需要等待第一次計算完成才能告訴你第二個計算是什么。 “applicative do”符號恰好存在於利用這種可能性。

  2. Applicative任何其他候選實例是否滿足Applicative法律,即使他們不同意所需的ap實例? :是的。 問題提出的“倒退”實例就是這樣的事情。 事實上,正如另一個答案所指出的那樣,任何一個應用都可以倒退,結果往往是一個不同的野獸。

對於讀者的進一步示例和練習,請注意非空列表以普通列表中熟悉的方式是monadic。

  data Nellist x = x :& Maybe (Nellist x)

  necat :: Nellist x -> Nellist x -> Nellist x
  necat (x :& Nothing) ys = x :& Just ys
  necat (x :& Just xs) ys = x :& Just (necat xs ys)

  instance Monad Nellist where
    return x = x :& Nothing
    (x :& Nothing) >>= k = k x
    (x :& Just xs) >>= k = necat (k x) (xs >>= k)

找到符合適用法律的至少四個行為不同的Applicative Nellist實例。

讓我們從一個顯而易見的事實開始: <*>這種定義違反了ap <*> ,即<*>應該是ap ,其中apMonad類中定義的那個,即你發布的第一個。

除了瑣事之外,據我所知,其他適用法律應該成立。

更具體地說,讓我們關注你提到的構成法。 你的“逆轉” ap

(<**>) m1 m2 = do { x <- m2 ; f <- m1 ; return (f x) }

也可以定義為

(<**>) m1 m2 = pure (flip ($)) <*> m2 <*> m1

其中<*>是“常規” ap

這意味着,例如,

u <**> (v <**> w) =
  { def. <**> }
pure (flip ($)) <*> (v <**> w) <*> u =
  { def. <**> }
pure (flip ($)) <*> (pure (flip ($)) <*> w <*> v) <*> u =
  { composition law }
pure (.) <*> pure (flip ($)) <*> (pure (flip ($)) <*> w) <*> v <*> u =
  { homomorphism law }
pure ((.) (flip ($))) <*> (pure (flip ($)) <*> w) <*> v <*> u =
  { composition law }
pure (.) <*> pure ((.) (flip ($))) <*> pure (flip ($)) <*> w <*> v <*> u =
  { homomorphism law (x2)}
pure ((.) ((.) (flip ($))) (flip ($))) <*> w <*> v <*> u =
  { beta reduction (several) }
pure (\x f g -> g (f x)) <*> w <*> v <*> u

(我希望我一切都好)

嘗試做類似於左手邊的事情。

pure (.) <**> u <**> v <**> w = ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM