簡體   English   中英

在learnyouahaskell 教程中,這個“Prob”monad 的返回是如何工作的?

[英]How does it work the return in this "Prob" monad in the learnyouahaskell tutorial?

我在以下實現中無法理解執行 flipThree 的返回:

import Data.Ratio  
import Data.List   
newtype Prob a = Prob { getProb :: [(a,Rational)] } deriving Show  


 -- Functor
instance Functor Prob where  
    fmap f (Prob xs) = Prob $ map (\(x,p) -> (f x,p)) xs  

-- Applicative
instance Applicative Prob where
  pure x = Prob [(x,1%1)]
  Prob [(x,r)] <*> something = fmap x something

-- Flatten works as join for Monads
flatten :: Prob (Prob a) -> Prob a  
flatten (Prob xs) = Prob $ concat $ map multAll xs  
    where multAll (Prob innerxs,p) = map (\(x,r) -> (x,p*r)) innerxs 

-- Monad
instance Monad Prob where  
    return x = Prob [(x,1%1)]  
    m >>= f = flatten (fmap f m)  
    fail _ = Prob []  

data Coin = Heads | Tails deriving (Show, Eq)  

coin :: Prob Coin  
coin = Prob [(Heads,1%2),(Tails,1%2)]  

loadedCoin :: Prob Coin  
loadedCoin = Prob [(Heads,1%10),(Tails,9%10)]  


flipThree :: Prob Bool
flipThree = do  
    a <- coin  
    b <- coin  
    c <- loadedCoin  
    return (all (==Tails) [a,b,c])

我可以繼續執行 flipThree 直到到達以下行:

return (all (==Tails) [a,b,c])

根據我得到的結果,如下:

Prob {getProb = [(False,1 % 40),(False,9 % 40),(False,1 % 40),(False,9 % 40),(False,1 % 40),(False,9 % 40),(False,1 % 40),(True,9 % 40)]}

我可以看到它來自之前有這個:

Prob {getProb = [([Heads,Heads,Heads],1 % 40),([Heads,Heads,Tails],9 % 40),([Heads,Tails,Heads],1 % 40),([Heads,Tails,Tails],9 % 40),([Tails,Heads,Heads],1 % 40),([Tails,Heads,Tails],9 % 40),([Tails,Tails,Heads],1 % 40),([Tails,Tails,Tails],9 % 40)]}

只要我能看到列表 monad 的一些不確定性,但我不明白為什么。 我的問題是理解為什么 Coin 的所有可能結果都被連接在元組的第一個參數中,例如當我們得到這個時:

[([Heads,Heads,Heads],1 % 40),([Heads,Heads,Tails],9 % 40)]

當 Monad Prob 以不同的方式定義並且返回應該返回一個帶有 Rational 1 % 1 的 Prob 時,為什么 monad 列表會這樣做?

筆記:

教程鏈接在這里:

http://learnyouahaskell.com/for-a-few-monads-more#making-monads

我真的很感激你能提供的任何幫助,只要我整個星期都在理解這一切。

提前致謝。

Prob monad 的工作方式與 List monad 類似,除了它還跟蹤所有選擇的當前概率。 當你最終return一些東西時,這個當前概率乘以 1%1 來給出元組中的概率。

我們需要最后的 1%1,因為概率被設置為項的乘積,而這個乘積中的最后一項是 1%1。

下面是這個 monadic 表達式發生了什么的演練:

do a <- coin
   b <- coin
   return (a == b)
  1. a - ( v1 , p1 ) 選擇一個值和概率。 這將a設置為v1以及當前概率公式p1 * ... 的公式。 我們不會知道......是什么,直到到達 monadic 表達式末尾的 return 為止。
  2. b - ( v2 , p2 ) 選擇一個值和概率。 這將b設置為v2並且當前概率公式擴展為p1 * p2 * ...
  3. 計算布爾值a == b ,並通過將 ... 替換為 1%1 來完成當前的概率計算。 生成的 Prob 元組將是 (v1 == v2, p1 * p2 * 1)。

暫無
暫無

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

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